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

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;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy