All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.core.internal.runtime.PerformanceStatsProcessor Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2005, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM - Initial API and implementation
 *     Christoph Läubrich - remove reference to InternalPlatform.getDefault().log
 *******************************************************************************/
package org.eclipse.core.internal.runtime;

import java.io.PrintWriter;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.PerformanceStats.PerformanceListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

/**
 * Processes, records, and performs notification of performance events
 * that occur in the system.
 */
public class PerformanceStatsProcessor extends Job {
	private static final PerformanceStatsProcessor instance = new PerformanceStatsProcessor();

	private static final long SCHEDULE_DELAY = 2000;

	/**
	 * Events that have occurred but have not yet been broadcast.
	 */
	private final ArrayList changes = new ArrayList<>();

	/**
	 * Event failures that have occurred but have not yet been broadcast.
	 * Maps (PerformanceStats -> Long).
	 */
	private final HashMap failures = new HashMap<>();

	/**
	 * Event listeners.
	 */
	private final ListenerList listeners = new ListenerList<>();

	private FrameworkLog log;

	/*
	 * @see PerformanceStats#addListener
	 */
	public static void addListener(PerformanceListener listener) {
		instance.listeners.add(listener);
	}

	/**
	 * Records the fact that an event occurred.
	 *
	 * @param stats The event that occurred
	 */
	public static void changed(PerformanceStats stats) {
		synchronized (instance) {
			instance.changes.add(stats);
		}
		instance.schedule(SCHEDULE_DELAY);
	}

	/**
	 * Records the fact that an event failed.
	 *
	 * @param stats The event that occurred
	 * @param pluginId The id of the plugin that declared the blame object, or
	 * null
	 * @param elapsed The elapsed time for this failure
	 */
	public static void failed(PerformanceStats stats, String pluginId, long elapsed) {
		synchronized (instance) {
			instance.failures.put(stats, Long.valueOf(elapsed));
		}
		instance.schedule(SCHEDULE_DELAY);
		instance.logFailure(stats, pluginId, elapsed);
	}

	/*
	 * @see PerformanceStats#printStats(PrintWriter)
	 */
	public static void printStats(PrintWriter out) {
		/* gather totals */
		long totalTime = 0;
		int totalCount = 0;
		PerformanceStats[] allStats = PerformanceStats.getAllStats();
		for (PerformanceStats stats : allStats) {
			totalTime += stats.getRunningTime();
			totalCount += stats.getRunCount();
		}
		//dump stats
		out.println("---------------------------------------------------------------"); //$NON-NLS-1$
		for (PerformanceStats stats : allStats) {
			out.print("Event: "); //$NON-NLS-1$
			out.print(stats.getEvent());
			out.print(" Blame: "); //$NON-NLS-1$
			out.print(stats.getBlameString());
			if (stats.getContext() != null) {
				out.print(" Context: "); //$NON-NLS-1$
				out.print(stats.getContext());
			}
			out.println();

			int runCount = stats.getRunCount();
			if (runCount > 0) {
				out.print("Run count: "); //$NON-NLS-1$
				out.print(Integer.toString(runCount));
				out.print(" ("); //$NON-NLS-1$
				out.print(Integer.toString((int) (runCount * 100.0 / totalCount)));
				out.println(" % of total)"); //$NON-NLS-1$
			}

			long runTime = stats.getRunningTime();
			if (runTime > 0) {
				out.print("Duration (ms): "); //$NON-NLS-1$
				out.print(Long.toString(runTime));
				out.print(" ("); //$NON-NLS-1$
				out.print(Integer.toString((int) (runTime * 100.0 / totalTime)));
				out.println(" % of total)"); //$NON-NLS-1$
			}
			out.println(""); //$NON-NLS-1$
		}
	}

	/*
	 * @see PerformanceStats#removeListener
	 */
	public static void removeListener(PerformanceListener listener) {
		instance.listeners.remove(listener);
	}

	/**
	 * Private constructor to enforce singleton usage.
	 */
	private PerformanceStatsProcessor() {
		super("Performance Stats"); //$NON-NLS-1$
		setSystem(true);
		setPriority(DECORATE);
		BundleContext context = PlatformActivator.getContext();
		String filter = '(' + FrameworkLog.SERVICE_PERFORMANCE + '=' + Boolean.TRUE + ')';
		Collection> references;
		FrameworkLog perfLog = null;
		try {
			references = context.getServiceReferences(FrameworkLog.class, filter);
			if (references != null && !references.isEmpty()) {
				//just take the first matching service
				perfLog = context.getService(references.iterator().next());
				//make sure correct location is set
				IPath logLocation = Platform.getLogFileLocation();
				logLocation = logLocation.removeLastSegments(1).append("performance.log"); //$NON-NLS-1$
				perfLog.setFile(logLocation.toFile(), false);
			}
		} catch (Exception e) {
			IStatus error = new Status(IStatus.ERROR, Platform.PI_RUNTIME, 1, "Error loading performance log", e); //$NON-NLS-1$
			RuntimeLog.log(error);
		}
		//use the platform log if we couldn't create the performance log
		if (perfLog == null)
			perfLog = InternalPlatform.getDefault().getFrameworkLog();
		log = perfLog;
	}

	/**
	 * Logs performance event failures to the platform's performance log
	 */
	private void logFailure(PerformanceStats stats, String pluginId, long elapsed) {
		//may have failed to get the performance log service
		if (log == null)
			return;
		if (pluginId == null)
			pluginId = Platform.PI_RUNTIME;
		String msg = "Performance failure: " + stats.getEvent() + " blame: " + stats.getBlameString() + " context: " + stats.getContext() + " duration: " + elapsed; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
		Status status = new Status(IStatus.WARNING, pluginId, 1, msg, new RuntimeException());
		log.log(new FrameworkLogEntry(status, status.getPlugin(), status.getSeverity(), status.getCode(), status.getMessage(), 0, status.getException(), null));

	}

	/*
	 * @see Job#run(IProgressMonitor)
	 */
	@Override
	protected IStatus run(IProgressMonitor monitor) {
		PerformanceStats[] events;
		PerformanceStats[] failedEvents;
		Long[] failedTimes;
		synchronized (this) {
			events = changes.toArray(new PerformanceStats[changes.size()]);
			changes.clear();
			failedEvents = failures.keySet().toArray(new PerformanceStats[failures.size()]);
			failedTimes = failures.values().toArray(new Long[failures.size()]);
			failures.clear();
		}

		//notify performance listeners
		for (PerformanceListener listener : listeners) {
			if (events.length > 0)
				listener.eventsOccurred(events);
			for (int j = 0; j < failedEvents.length; j++)
				listener.eventFailed(failedEvents[j], failedTimes[j].longValue());
		}
		schedule(SCHEDULE_DELAY);
		return Status.OK_STATUS;
	}

	/*
	 * @see Job#shouldRun()
	 */
	@Override
	public boolean shouldRun() {
		return !changes.isEmpty() || !failures.isEmpty();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy