package org.sonar.plugins.profiler;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.Phase;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.JavaFile;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.utils.SonarException;
import org.sonar.plugins.profiler.jprofiler.JProfilerExporter;
import org.sonar.plugins.profiler.utils.FilterFilesBySuffix;
import java.io.File;
import java.io.IOException;
/**
* @author Evgeny Mandrikov
*/
@Phase(name = Phase.Name.POST)
public class ProfilerSensor implements Sensor {
private static final Logger LOG = LoggerFactory.getLogger(ProfilerSensor.class);
private String getJProfilerHome(Project project) {
return project.getConfiguration().getString(ProfilerPlugin.JPROFILER_HOME_PROPERTY);
}
public boolean shouldExecuteOnProject(Project project) {
String jProfilerHome = getJProfilerHome(project);
return !StringUtils.isBlank(jProfilerHome) && new File(jProfilerHome).isDirectory();
}
/**
* @param project project
* @return ${basedir}/target/profiler
*/
private File getDir(Project project) {
return new File(project.getFileSystem().getBuildDir(), "/profiler");
}
public void analyse(Project project, SensorContext context) {
try {
File dir = getDir(project);
LOG.info("Parsing {}", dir);
exportDir(getJProfilerHome(project), dir);
File[] files;
files = dir.listFiles(new FilterFilesBySuffix("-" + JProfilerExporter.HOTSPOTS_VIEW + ".html"));
for (File file : files) {
context.saveMeasure(getProfilerResource(file), ProfilerMetrics.TESTS, 1.0); // TODO
saveMeasure(ProfilerMetrics.CPU_HOTSPOTS_DATA, file, context);
}
files = dir.listFiles(new FilterFilesBySuffix("-" + JProfilerExporter.ALLOCATION_HOTSPOTS_VIEW + ".html"));
for (File file : files) {
saveMeasure(ProfilerMetrics.MEMORY_HOTSPOTS_DATA, file, context);
}
} catch (Exception e) {
throw new SonarException(e);
}
}
protected void saveMeasure(Metric metric, File file, SensorContext context) throws IOException {
Measure measure = new Measure(metric);
String data = FileUtils.readFileToString(file);
measure.setData(data);
Resource<?> resource = getProfilerResource(file);
LOG.info("Saving {} for {} from {}", new Object[]{metric.getName(), resource.getKey(), file});
context.saveMeasure(resource, measure);
}
protected Resource<?> getProfilerResource(File file) {
// TODO support multiple snapshots for one test file
String key = StringUtils.substringBeforeLast(file.getName(), "-");
return new JavaFile(key, true);
}
@Override
public String toString() {
return getClass().getSimpleName();
}
private void exportDir(String jProfilerHome, File dir) {
for (String filename : dir.list(new FilterFilesBySuffix(JProfilerExporter.JPS_EXT))) {
JProfilerExporter.create(jProfilerHome, dir, filename)
.setExportDir(dir)
.addHotSpotsView(JProfilerExporter.HTML_FORMAT, "method", "method", false)
.addAllocationHotSpotsView(JProfilerExporter.HTML_FORMAT, "method", false)
.export();
}
}
}