1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

codan - tracing options for printing checker stats

Change-Id: Ia0d1be6fc6be6092ae4b1dac84dff24fb722b1d5
This commit is contained in:
Alena Laskavaia 2015-03-02 22:27:29 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent 7a245a2520
commit a1b9cc4fbd
4 changed files with 146 additions and 32 deletions

View file

@ -0,0 +1,4 @@
org.eclipse.cdt.codan.core/debug=false
# Reports checkers performance on stdout when calling analysis on demand
org.eclipse.cdt.codan.core/debug/performance=false

View file

@ -10,13 +10,18 @@
*******************************************************************************/
package org.eclipse.cdt.codan.core;
import org.eclipse.cdt.codan.internal.core.CheckersTimeStats;
import org.eclipse.cdt.codan.internal.core.CodeAnalysisNature;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugTrace;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
/**
* The activator class controls the plug-in life cycle
@ -31,6 +36,8 @@ public class CodanCorePlugin extends Plugin {
public static final String NATURE_ID = CodeAnalysisNature.NATURE_ID;
// The shared instance
private static CodanCorePlugin plugin;
private static DebugTrace trace;
private static DebugOptions debugOptions;
/**
* The constructor
@ -55,6 +62,9 @@ public class CodanCorePlugin extends Plugin {
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
if (isDebuggingEnabled("/debug/performance")) { //$NON-NLS-1$
CheckersTimeStats.getInstance().setEnabled(true);
}
}
/*
@ -120,4 +130,70 @@ public class CodanCorePlugin extends Plugin {
public static void log(String message) {
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, message, null));
}
private final boolean isDebuggingEnabled(final String optionPath) {
if (optionPath == null)
return true;
if (debugOptions==null)
getTrace();
if (debugOptions==null)
return false;
boolean debugEnabled = false;
if (debugOptions.isDebugEnabled()) {
final String option = getDefault().getBundle().getSymbolicName() + optionPath;
debugEnabled = debugOptions.getBooleanOption(option, false);
}
return debugEnabled;
}
/**
* Use a no-op trace when a real one isn't available. Simplifies life for
* clients; no need to check for null.
*/
private static final DebugTrace NULL_TRACE = new DebugTrace() {
@Override
public void trace(String option, String message) {}
@Override
public void trace(String option, String message, Throwable error) {}
@Override
public void traceDumpStack(String option) {}
@Override
public void traceEntry(String option) {}
@Override
public void traceEntry(String option, Object methodArgument) {}
@Override
public void traceEntry(String option, Object[] methodArguments) {}
@Override
public void traceExit(String option) {}
@Override
public void traceExit(String option, Object result) {}
};
synchronized private static DebugTrace getTrace() {
if (trace == null) {
Plugin plugin = getDefault();
if (plugin != null) {
Bundle bundle = plugin.getBundle();
if (bundle != null) {
BundleContext context = bundle.getBundleContext();
if (context != null) {
ServiceTracker<DebugOptions, DebugOptions> tracker = new ServiceTracker<DebugOptions, DebugOptions>(context, DebugOptions.class.getName(), null);
try {
tracker.open();
debugOptions = tracker.getService();
if (debugOptions != null) {
trace = debugOptions.newDebugTrace(bundle.getSymbolicName());
}
}
finally {
tracker.close();
}
}
}
}
}
return trace != null ? trace : NULL_TRACE;
}
}

View file

@ -21,6 +21,7 @@ public class CheckersTimeStats {
public static final String ALL = "ALL"; //$NON-NLS-1$
public static final String ELAPSED = "ELAPSED"; //$NON-NLS-1$
private static CheckersTimeStats instance = new CheckersTimeStats();
private boolean enableStats = false;
/**
* @return global instance of stats
@ -44,16 +45,15 @@ public class CheckersTimeStats {
current = 0;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
if (count != 0)
return duration + " " + count + " " + duration / count; //$NON-NLS-1$//$NON-NLS-2$
return ""; //$NON-NLS-1$
return String.format("%4d %4d %4.2f", duration, count, count == 0 ? count : (duration / (float) count)); //$NON-NLS-1$
}
public String toString(long total) {
float ave = count == 0 ? count : (duration / (float) count);
float per = total == 0 ? 100f : (duration * 100 / (float) total);
return String.format("%4d %4d %4.2f %4.2f%%", duration, count, ave, per); //$NON-NLS-1$
}
}
private Map<String, TimeRecord> records = new HashMap<String, TimeRecord>();
@ -87,8 +87,14 @@ public class CheckersTimeStats {
* @param counter
*/
public void checkerStart(String id, String counter) {
TimeRecord record = getTimeRecord(id + ":" + counter); //$NON-NLS-1$
record.start();
if (enableStats) {
TimeRecord record = getTimeRecord(getKey(id, counter));
record.start();
}
}
private String getKey(String id, String counter) {
return id + ":" + counter; //$NON-NLS-1$
}
/**
@ -96,7 +102,9 @@ public class CheckersTimeStats {
* @param counter
*/
public void checkerStop(String id, String counter) {
getTimeRecord(id + ":" + counter).stop(); //$NON-NLS-1$
if (enableStats) {
getTimeRecord(getKey(id, counter)).stop();
}
}
/**
@ -107,11 +115,12 @@ public class CheckersTimeStats {
}
/**
*
* Print checker stats to stdout if tracing enabled
*/
public void traceStats() {
// TODO: add check for trace flags
printStats();
if (enableStats) {
printStats();
}
}
/**
@ -119,11 +128,16 @@ public class CheckersTimeStats {
*/
public void printStats() {
System.out.println("---"); //$NON-NLS-1$
String totalId = getKey(ALL, ELAPSED);
TimeRecord all = records.get(totalId);
for (Iterator<String> iterator = records.keySet().iterator(); iterator.hasNext();) {
String id = iterator.next();
if (id.equals(totalId))
continue;
TimeRecord timeRecord = getTimeRecord(id);
System.out.println(timeRecord.toString() + " " + id); //$NON-NLS-1$
System.out.println(timeRecord.toString(all.duration) + " " + id); //$NON-NLS-1$
}
System.out.println(all.toString() + " " + totalId); //$NON-NLS-1$
}
/**
@ -132,4 +146,18 @@ public class CheckersTimeStats {
public void reset() {
records.clear();
}
/**
* @return true is stats collection is enabled
*/
public boolean isEnabled() {
return enableStats;
}
/**
* @param set to true to enable stats collection and false to disable
*/
public void setEnabled(boolean enableStats) {
this.enableStats = enableStats;
}
}

View file

@ -14,6 +14,7 @@ import java.util.Iterator;
import org.eclipse.cdt.codan.core.CodanRuntime;
import org.eclipse.cdt.codan.core.model.CheckerLaunchMode;
import org.eclipse.cdt.codan.internal.core.CheckersTimeStats;
import org.eclipse.cdt.codan.internal.ui.CodanUIMessages;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
@ -43,26 +44,31 @@ public class RunCodeAnalysis implements IObjectActionDelegate {
Job job = new Job(CodanUIMessages.Job_TitleRunningAnalysis) {
@Override
protected IStatus run(final IProgressMonitor monitor) {
int count = ss.size();
monitor.beginTask(getName(), count * 100);
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
for (Iterator iterator = ss.iterator(); iterator.hasNext();) {
Object o = iterator.next();
if (o instanceof IAdaptable) {
o = ((IAdaptable) o).getAdapter(IResource.class);
}
if (o instanceof IResource) {
IResource res = (IResource) o;
SubProgressMonitor subMon = new SubProgressMonitor(monitor, 100);
CodanRuntime.getInstance().getBuilder().processResource(res, subMon, CheckerLaunchMode.RUN_ON_DEMAND);
if (subMon.isCanceled())
return Status.CANCEL_STATUS;
}
try {
int count = ss.size();
monitor.beginTask(getName(), count * 100);
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
for (Iterator iterator = ss.iterator(); iterator.hasNext();) {
Object o = iterator.next();
if (o instanceof IAdaptable) {
o = ((IAdaptable) o).getAdapter(IResource.class);
}
if (o instanceof IResource) {
IResource res = (IResource) o;
SubProgressMonitor subMon = new SubProgressMonitor(monitor, 100);
CodanRuntime.getInstance().getBuilder().processResource(res, subMon, CheckerLaunchMode.RUN_ON_DEMAND);
if (subMon.isCanceled())
return Status.CANCEL_STATUS;
}
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
} finally {
CheckersTimeStats.getInstance().traceStats();
CheckersTimeStats.getInstance().reset();
}
return Status.OK_STATUS;
}
};
job.setUser(true);