de.dagere.peass.execution.kieker.KiekerEnvironmentPreparer Maven / Gradle / Ivy
The newest version!
package de.dagere.peass.execution.kieker;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.dagere.peass.config.KiekerConfig;
import de.dagere.peass.config.MeasurementConfig;
import de.dagere.peass.execution.maven.pom.MavenTestExecutor;
import de.dagere.peass.folders.PeassFolders;
import de.dagere.peass.testtransformation.TestTransformer;
import net.kieker.sourceinstrumentation.AllowedKiekerRecord;
import net.kieker.sourceinstrumentation.InstrumentationConfiguration;
import net.kieker.sourceinstrumentation.instrument.InstrumentKiekerSource;
public class KiekerEnvironmentPreparer {
private static final Logger LOG = LogManager.getLogger(KiekerEnvironmentPreparer.class);
private static final String[] metaInfFolders = new String[] { "src/main/resources/META-INF", "src/java/META-INF", "src/test/resources/META-INF", "src/test/META-INF",
"target/test-classes/META-INF" };
private final Set includedMethodPattern;
private final List existingClasses;
private final PeassFolders folders;
private final TestTransformer testTransformer;
private List modules;
public KiekerEnvironmentPreparer(final Set includedMethodPattern, final List existingClasses, final PeassFolders folders, final TestTransformer testTransformer,
final List modules) {
this.includedMethodPattern = includedMethodPattern;
this.existingClasses = existingClasses;
this.folders = folders;
this.testTransformer = testTransformer;
this.modules = modules;
}
public void prepareKieker() {
final MeasurementConfig config = testTransformer.getConfig();
KiekerConfig kiekerConfig = config.getKiekerConfig();
try {
if (kiekerConfig.isUseSourceInstrumentation() && !kiekerConfig.isOnlyOneCallRecording()) {
instrumentSources(config);
} else {
if (kiekerConfig.isEnableAdaptiveMonitoring()) {
prepareAdaptiveExecution();
}
if (kiekerConfig.isOnlyOneCallRecording()) {
generateAOPXML("de.dagere.kopeme.kieker.probe.OneCallAspectFull");
} else if (AllowedKiekerRecord.DURATION.equals(kiekerConfig.getRecord())) {
generateAOPXML(AllowedKiekerRecord.DURATION.getFullName());
} else {
generateAOPXML(AllowedKiekerRecord.OPERATIONEXECUTION.getFullName());
}
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
generateKiekerMonitoringProperties();
}
private void instrumentSources(final MeasurementConfig config) throws IOException {
final InstrumentKiekerSource instrumentKiekerSource;
LOG.debug("Create default constructor: {}", config.getKiekerConfig().isCreateDefaultConstructor());
final LinkedHashSet excludedPatterns = config.getKiekerConfig().getExcludeForTracing();
buildJettyExclusion(excludedPatterns);
instrumentKiekerSource = buildInstrumenter(config, excludedPatterns);
instrumentModules(config, instrumentKiekerSource);
if (config.getKiekerConfig().isEnableAdaptiveMonitoring()) {
writeConfig();
}
}
private void instrumentModules(final MeasurementConfig config, final InstrumentKiekerSource instrumentKiekerSource) throws IOException {
for (File module : modules) {
List allClazzFolders = config.getExecutionConfig().getAllClazzFolders();
File[] files = new File[allClazzFolders.size()];
for (int i = 0; i < allClazzFolders.size(); i++) {
files[i] = new File(module, allClazzFolders.get(i));
}
instrumentKiekerSource.instrumentProject(files);
}
}
private InstrumentKiekerSource buildInstrumenter(final MeasurementConfig config, final HashSet excludedPatterns) {
final InstrumentKiekerSource instrumentKiekerSource;
AllowedKiekerRecord record = config.getKiekerConfig().getRecord();
boolean createDefaultConstructor = config.getKiekerConfig().isCreateDefaultConstructor();
boolean adaptiveInstrumentation = config.getKiekerConfig().isAdaptiveInstrumentation();
int repetitions = config.getRepetitions();
boolean extractMethod = config.getKiekerConfig().isExtractMethod();
boolean strictMode = false;
if (config.getExecutionConfig().isUseAnbox()) {
strictMode = true;
}
if (!config.getKiekerConfig().isUseSelectiveInstrumentation()) {
InstrumentationConfiguration kiekerConfiguration = new InstrumentationConfiguration(record, false,
createDefaultConstructor,
adaptiveInstrumentation, includedMethodPattern, excludedPatterns, false, repetitions,
extractMethod, strictMode);
instrumentKiekerSource = new InstrumentKiekerSource(kiekerConfiguration);
} else {
InstrumentationConfiguration kiekerConfiguration = new InstrumentationConfiguration(record, config.getKiekerConfig().isUseAggregation(),
createDefaultConstructor,
adaptiveInstrumentation, includedMethodPattern, excludedPatterns, true, repetitions,
extractMethod, strictMode);
instrumentKiekerSource = new InstrumentKiekerSource(kiekerConfiguration);
}
return instrumentKiekerSource;
}
private void buildJettyExclusion(final HashSet excludedPatterns) {
for (String notInstrumenting : new String[] { "org.eclipse.jetty.logging.JettyLevel", "org.eclipse.jetty.logging.JettyLoggerConfiguration",
"org.eclipse.jetty.logging.JettyLoggingServiceProvider", "org.eclipse.jetty.logging.JettyLoggerFactory", "org.eclipse.jetty.logging.StdErrAppender",
"org.eclipse.jetty.logging.Timestamp", "org.eclipse.jetty.logging.Timestamp$Tick",
"org.eclipse.jetty.logging.JettyLogger" }) {
excludedPatterns.add("new " + notInstrumenting + ".(..)");
excludedPatterns.add("* " + notInstrumenting + ".*(..)"); // package visibility things from JettyLoggingServiceProvider with any return
excludedPatterns.add("*[] " + notInstrumenting + ".*(..)");
excludedPatterns.add("*.* " + notInstrumenting + ".*(..)");
excludedPatterns.add("*.*.* " + notInstrumenting + ".*(..)");
excludedPatterns.add("*.*.*.* " + notInstrumenting + ".*(..)");
excludedPatterns.add("*.*.*.*.* " + notInstrumenting + ".*(..)");
}
}
private void generateKiekerMonitoringProperties() {
try {
for (final File module : modules) {
for (final String potentialReadFolder : metaInfFolders) {
final File folder = new File(module, potentialReadFolder);
folder.mkdirs();
final File propertiesFile = new File(folder, "kieker.monitoring.properties");
AOPXMLHelper.writeKiekerMonitoringProperties(propertiesFile, testTransformer, folders);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void prepareAdaptiveExecution() throws IOException, InterruptedException {
if (!MavenTestExecutor.KIEKER_ASPECTJ_JAR.exists()) {
// This can be removed if Kieker 1.14 is released
throw new RuntimeException("Tweaked Kieker " + MavenTestExecutor.KIEKER_ASPECTJ_JAR + " needs to exist - git clone https://github.com/DaGeRe/kieker -b 1_13_tweak "
+ "and install manually!");
}
writeConfig();
}
private void writeConfig() throws IOException {
final File configFolder = new File(folders.getProjectFolder(), "config");
configFolder.mkdir();
final File adaptiveFile = new File(folders.getProjectFolder(), MavenTestExecutor.KIEKER_ADAPTIVE_FILENAME);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(adaptiveFile))) {
writer.write("- *\n");
for (final String includedMethod : includedMethodPattern) {
writer.write("+ " + includedMethod + "\n");
}
writer.flush();
}
}
private void generateAOPXML(final String aspectName) {
try {
for (final File module : modules) {
for (final String potentialReadFolder : metaInfFolders) {
final File folder = new File(module, potentialReadFolder);
folder.mkdirs();
final File goalFile2 = new File(folder, "aop.xml");
final Set clazzes = getClazzSet();
AOPXMLHelper.writeAOPXMLToFile(new LinkedList(clazzes), goalFile2, aspectName);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Set getClazzSet() {
final Set clazzes = new HashSet();
if (includedMethodPattern != null) {
for (String method : includedMethodPattern) {
final String methodBeforeParameters = method.substring(0, method.indexOf('('));
final String clazz = methodBeforeParameters.substring(methodBeforeParameters.lastIndexOf(' ') + 1, methodBeforeParameters.lastIndexOf('.'));
clazzes.add(clazz);
}
} else {
clazzes.addAll(existingClasses);
}
return clazzes;
}
}