/******************************************************************************* * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.osgi.internal.profile; import org.eclipse.osgi.framework.debug.FrameworkDebugOptions; import org.eclipse.osgi.framework.internal.core.FrameworkProperties; /** * This class is a development tool that provides a simple way to log * programmer defined timmings for performance evaluations. This profiling * allows logging of a timestamp with a corresponding message to a trace * buffer. */ public class Profile { /** * Profiling is enabled and available. */ public static final boolean PROFILE = true; // enable profile compiling /** * The logging state of <tt>STARTUP</tt> messages */ public static boolean STARTUP = false; // enable startup profiling /** * The logging state of <tt>BENCHMARK</tt> messages */ public static boolean BENCHMARK = false; // enable all benchmarking /** * The logging state of <tt>DEBUG</tt> messages */ public static boolean DEBUG = false; // enable general debug profiling private static final String OSGI_PROP = "osgi.profile."; //$NON-NLS-1$ private static final String PROP_STARTUP = OSGI_PROP + "startup"; //$NON-NLS-1$ private static final String PROP_BENCHMARK = OSGI_PROP + "benchmark"; //$NON-NLS-1$ private static final String PROP_DEBUG = OSGI_PROP + "debug"; //$NON-NLS-1$ private static final String PROP_IMPL = OSGI_PROP + "impl"; //$NON-NLS-1$ private static final String OSGI_OPTION = "org.eclipse.osgi/profile/"; //$NON-NLS-1$ private static final String OPTION_STARTUP = OSGI_OPTION + "startup"; //$NON-NLS-1$ private static final String OPTION_BENCHMARK = OSGI_OPTION + "benchmark"; //$NON-NLS-1$ private static final String OPTION_DEBUG = OSGI_OPTION + "debug"; //$NON-NLS-1$ private static final String OPTION_IMPL = OSGI_OPTION + "impl"; //$NON-NLS-1$ /** * The default logging flag. */ public static final int FLAG_NONE = 0; /** * The logging flag for <strong>method enter</strong> */ public static final int FLAG_ENTER = 1; /** * The logging flag for <strong>method exit</strong> */ public static final int FLAG_EXIT = 2; /** * The description for <strong>method enter</strong> */ public static final String ENTER_DESCRIPTION = "enter"; //$NON-NLS-1$ /** * The description for <strong>method exit</strong> */ public static final String EXIT_DESCRIPTION = "exit"; //$NON-NLS-1$ private static ProfileLogger profileLogger = null; private static String profileLoggerClassName = null; static { initProps(); } /** * Initialize/update profiling properties. * * If profiling properties are updated, this method is called to update * the profile states. */ public static void initProps() { String prop; FrameworkDebugOptions dbgOptions = null; // if osgi.debug is not available, don't force DebugOptions // to init as this variable may be set later on where // DebugOptions will succeed. if (FrameworkProperties.getProperty("osgi.debug") != null) { //$NON-NLS-1$ dbgOptions = FrameworkDebugOptions.getDefault(); if (dbgOptions != null) { STARTUP = dbgOptions.getBooleanOption(OPTION_STARTUP, false); BENCHMARK = dbgOptions.getBooleanOption(OPTION_BENCHMARK, false); DEBUG = dbgOptions.getBooleanOption(OPTION_DEBUG, false); if (profileLogger == null) profileLoggerClassName = dbgOptions.getOption(OPTION_IMPL); } } // System properties will always override anything in .options file if ((prop = FrameworkProperties.getProperty(PROP_STARTUP)) != null) { STARTUP = Boolean.valueOf(prop).booleanValue(); if (dbgOptions != null) dbgOptions.setOption(OPTION_STARTUP, new Boolean(STARTUP).toString()); } if ((prop = FrameworkProperties.getProperty(PROP_BENCHMARK)) != null) { BENCHMARK = Boolean.valueOf(prop).booleanValue(); if (dbgOptions != null) dbgOptions.setOption(OPTION_BENCHMARK, new Boolean(BENCHMARK).toString()); } if ((prop = FrameworkProperties.getProperty(PROP_DEBUG)) != null) { DEBUG = Boolean.valueOf(prop).booleanValue(); if (dbgOptions != null) dbgOptions.setOption(OPTION_DEBUG, new Boolean(DEBUG).toString()); } if (profileLogger == null) { if ((prop = FrameworkProperties.getProperty(PROP_IMPL)) != null) { profileLoggerClassName = prop; if (dbgOptions != null) dbgOptions.setOption(OPTION_IMPL, profileLoggerClassName); } } else { profileLogger.initProps(); } } /** * Log a method enter. * * @param id The method's unique identification (e.g. org.eclipse.class#name). */ public static void logEnter(String id) { logTime(FLAG_ENTER, id, ENTER_DESCRIPTION, null); } /** * Log a method enter. * * @param id The method's unique identification (e.g. org.eclipse.class#name). * @param description A description of the method. */ public static void logEnter(String id, String description) { logTime(FLAG_ENTER, id, ENTER_DESCRIPTION, description); } /** * Log a method exit. * * @param id The method's unique identification (e.g. org.eclipse.class#name). */ public static void logExit(String id) { logTime(FLAG_EXIT, id, EXIT_DESCRIPTION, null); } /** * Log a method exit. * * @param id The method's unique identification (e.g. org.eclipse.class#name). * @param description A description of the method. */ public static void logExit(String id, String description) { logTime(FLAG_EXIT, id, EXIT_DESCRIPTION, description); } /** * Log a message. * * @param id The method's unique identification (e.g. org.eclipse.class#name). * @param msg The message. */ public static void logTime(String id, String msg) { logTime(FLAG_NONE, id, msg, null); } /** * Log a message. * * @param id The method's unique identification (e.g. org.eclipse.class#name). * @param msg The message. * @param description A description of the method. */ public static void logTime(String id, String msg, String description) { logTime(FLAG_NONE, id, msg, description); } /** * Log a message. * * @param flag A profile logging flag. * @param id The method's unique identification (e.g. org.eclipse.class#name). * @param msg The message. * @param description A description of the method. * * @see #FLAG_ENTER * @see #FLAG_EXIT * @see #FLAG_NONE */ public static void logTime(int flag, String id, String msg, String description) { if (profileLogger == null) profileLogger = createProfileLogger(); profileLogger.logTime(flag, id, msg, description); } /** * Use cumulative logging to record the entrance from this scope. * * @param scope The entering scope */ public static void accumLogEnter(String scope) { if (profileLogger == null) profileLogger = createProfileLogger(); profileLogger.accumLogEnter(scope); } /** * Use cumulative logging to record the exit from this scope. * * @param scope The exiting scope */ public static void accumLogExit(String scope) { if (profileLogger == null) profileLogger = createProfileLogger(); profileLogger.accumLogExit(scope); } /** * Get the profiling log report and reset the trace buffer. * * @return The profiling log report. */ public static String getProfileLog() { if (profileLogger != null) return profileLogger.getProfileLog(); return ""; //$NON-NLS-1$ } /** * Create an instance of the appropriate profile logger */ private static ProfileLogger createProfileLogger() { ProfileLogger result = null; // Try to create it by class name if (profileLoggerClassName != null) { Class<?> profileImplClass = null; try { profileImplClass = Class.forName(profileLoggerClassName); result = (ProfileLogger) profileImplClass.newInstance(); } catch (Exception e) { // could not find the class e.printStackTrace(); } } // Use the default if (result == null) result = new DefaultProfileLogger(); return (result); } }