
com.mgmtp.perfload.perfalyzer.PerfAlyzerModule Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2013-2015 mgm technology partners GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mgmtp.perfload.perfalyzer;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.spi.Message;
import com.google.inject.util.Providers;
import com.mgmtp.perfload.perfalyzer.annotations.BinnedDir;
import com.mgmtp.perfload.perfalyzer.annotations.DoBinning;
import com.mgmtp.perfload.perfalyzer.annotations.DoNormalization;
import com.mgmtp.perfload.perfalyzer.annotations.DoReportPreparation;
import com.mgmtp.perfload.perfalyzer.annotations.EmailFrom;
import com.mgmtp.perfload.perfalyzer.annotations.EmailTo;
import com.mgmtp.perfload.perfalyzer.annotations.FloatFormat;
import com.mgmtp.perfload.perfalyzer.annotations.IntFormat;
import com.mgmtp.perfload.perfalyzer.annotations.MaxEmailHistoryItems;
import com.mgmtp.perfload.perfalyzer.annotations.MaxHistoryItems;
import com.mgmtp.perfload.perfalyzer.annotations.NormalizedDir;
import com.mgmtp.perfload.perfalyzer.annotations.RelativeDestDir;
import com.mgmtp.perfload.perfalyzer.annotations.ReportDir;
import com.mgmtp.perfload.perfalyzer.annotations.ReportPreparationDir;
import com.mgmtp.perfload.perfalyzer.annotations.ReportTabNames;
import com.mgmtp.perfload.perfalyzer.annotations.ReportsBaseUrl;
import com.mgmtp.perfload.perfalyzer.annotations.SmtpProps;
import com.mgmtp.perfload.perfalyzer.annotations.SubjectProps;
import com.mgmtp.perfload.perfalyzer.annotations.UnzippedDir;
import com.mgmtp.perfload.perfalyzer.annotations.WarmUpSeconds;
import com.mgmtp.perfload.perfalyzer.reporting.ReportCreator;
import com.mgmtp.perfload.perfalyzer.reporting.email.EmailReporter;
import com.mgmtp.perfload.perfalyzer.reportpreparation.DisplayData;
import com.mgmtp.perfload.perfalyzer.reportpreparation.PlotCreator;
import com.mgmtp.perfload.perfalyzer.util.ArchiveExtracter;
import com.mgmtp.perfload.perfalyzer.util.Marker;
import com.mgmtp.perfload.perfalyzer.util.MarkersReader;
import com.mgmtp.perfload.perfalyzer.util.MemoryFormat;
import com.mgmtp.perfload.perfalyzer.util.ResourceBundleProvider;
import com.mgmtp.perfload.perfalyzer.util.ResourceBundleProvider.Utf8Control;
import com.mgmtp.perfload.perfalyzer.util.TestMetadata;
import com.mgmtp.perfload.perfalyzer.util.TimestampNormalizer;
import com.mgmtp.perfload.perfalyzer.workflow.GcLogWorkflow;
import com.mgmtp.perfload.perfalyzer.workflow.LoadProfileWorkflow;
import com.mgmtp.perfload.perfalyzer.workflow.MeasuringWorkflow;
import com.mgmtp.perfload.perfalyzer.workflow.PerfMonWorkflow;
import com.mgmtp.perfload.perfalyzer.workflow.Workflow;
import com.mgmtp.perfload.perfalyzer.workflow.WorkflowExecutor;
import groovy.util.ConfigObject;
import groovy.util.ConfigSlurper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Singleton;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import java.io.File;
import java.io.IOException;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.beust.jcommander.internal.Lists.newArrayList;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.collect.Lists.newArrayListWithCapacity;
import static com.mgmtp.perfload.perfalyzer.util.PropertiesUtils.loadIntoProperties;
import static com.mgmtp.perfload.perfalyzer.util.PropertiesUtils.loadProperties;
import static com.mgmtp.perfload.perfalyzer.util.PropertiesUtils.saveProperties;
import static com.mgmtp.perfload.perfalyzer.util.PropertiesUtils.setIfNonNull;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.io.FileUtils.deleteDirectory;
import static org.apache.commons.io.FileUtils.listFiles;
import static org.apache.commons.io.filefilter.FileFilterUtils.suffixFileFilter;
/**
* @author rnaegele
*/
public class PerfAlyzerModule extends AbstractModule {
public static final Pattern INPUT_DIR_PATTERN = Pattern.compile("(\\d{8}-\\d{4})_(.*)");
private final Logger log = LoggerFactory.getLogger(getClass());
private final PerfAlyzerArgs args;
public PerfAlyzerModule(final PerfAlyzerArgs args) {
checkState(!args.unzip || args.inputDir.isDirectory(), "'inputDir' does not exist or is not a directory: %s", args.inputDir);
this.args = args;
}
@SuppressWarnings("unchecked")
private static T get(final ConfigObject configObject, final String key) {
return (T) configObject.get(key);
}
@Override
protected void configure() {
binder().requireExplicitBindings();
bindConstant().annotatedWith(DoNormalization.class).to(args.normalization);
bindConstant().annotatedWith(DoBinning.class).to(args.binning);
bindConstant().annotatedWith(DoReportPreparation.class).to(args.reportPreparation);
String inputDirName = args.inputDir.getName();
Matcher matcher = INPUT_DIR_PATTERN.matcher(inputDirName);
checkState(matcher.matches(), "Input dir did not match pattern %s", INPUT_DIR_PATTERN);
String timestamp = matcher.group(1);
String testName = matcher.group(2);
File destDir = new File(new File(args.outputDir, testName), timestamp);
File unzippedDir = new File(destDir, "01_unzipped");
bind(File.class).annotatedWith(RelativeDestDir.class).toInstance(new File(testName, timestamp));
bind(File.class).annotatedWith(UnzippedDir.class).toInstance(unzippedDir);
bind(File.class).annotatedWith(NormalizedDir.class).toInstance(new File(destDir, "02_normalized"));
bind(File.class).annotatedWith(BinnedDir.class).toInstance(new File(destDir, "03_binned"));
bind(File.class).annotatedWith(ReportPreparationDir.class).toInstance(new File(destDir, "04_reportpreparation"));
bind(File.class).annotatedWith(ReportDir.class).toInstance(new File(destDir, "05_report"));
if (args.unzip) {
try {
if (unzippedDir.isDirectory()) {
log.info("Directory '{}' already exists. Deleting it...", unzippedDir);
deleteDirectory(unzippedDir);
}
log.info("Extracting result archives...");
ArchiveExtracter archiveExtracter = new ArchiveExtracter(args.inputDir, unzippedDir);
archiveExtracter.extract();
} catch (IOException ex) {
Throwables.propagate(ex);
}
} else {
checkState(unzippedDir.isDirectory(),
"Unzipping was turned off, but directory with unzipped files does not exist or is not a directory: %s",
unzippedDir);
}
createBindingsFromConfigFile(args.outputDir);
bindTestMetadata(unzippedDir);
Multibinder workflowBinder = Multibinder.newSetBinder(binder(), Workflow.class);
workflowBinder.addBinding().to(PerfMonWorkflow.class);
workflowBinder.addBinding().to(MeasuringWorkflow.class);
workflowBinder.addBinding().to(GcLogWorkflow.class);
workflowBinder.addBinding().to(LoadProfileWorkflow.class);
bind(WorkflowExecutor.class);
bind(PerfAlyzer.class);
bind(ReportCreator.class);
bind(ResourceBundle.class).toProvider(ResourceBundleProvider.class);
bind(PlotCreator.class);
bind(MemoryFormat.class);
}
private void bindTestMetadata(final File unzippedDir) {
File metaPropsFile = new File(unzippedDir, "console/console-logs/perfload.meta.utf8.props");
try {
Properties perfLoadMetaProps;
if (metaPropsFile.exists()) {
log.info("Loading test meta properties...");
perfLoadMetaProps = loadProperties(metaPropsFile);
} else {
log.warn("Testplan properties file does not exist: {}", metaPropsFile);
perfLoadMetaProps = new Properties();
}
// args override
setIfNonNull(perfLoadMetaProps, "test.start", args.testStartDate);
setIfNonNull(perfLoadMetaProps, "test.finish", args.testFinishDate);
setIfNonNull(perfLoadMetaProps, "test.comment", args.testComment);
setIfNonNull(perfLoadMetaProps, "operations", args.operations);
TestMetadata testMetadata = TestMetadata.create(args.inputDir.getName(), perfLoadMetaProps);
bind(TestMetadata.class).toInstance(testMetadata);
} catch (IOException ex) {
log.error("Error reading test meta properties: " + metaPropsFile, ex);
Throwables.propagate(ex);
}
}
private void createBindingsFromConfigFile(final File destDir) {
File configFile = new File("config", "PerfAlyzerConfig.groovy");
if (!configFile.exists()) {
log.info("Config file '{}' does not exist. Using default config file.", configFile);
configFile = new File("config", "PerfAlyzerConfig_Default.groovy");
}
try {
log.info("Loading perfAlyzer config file...");
ConfigSlurper slurper = new ConfigSlurper();
ConfigObject configObject = slurper.parse(configFile.toURI().toURL());
// wrapping into a provider caters for null
String url = get(configObject, "reportsBaseUrl");
bind(String.class).annotatedWith(ReportsBaseUrl.class).toProvider(Providers.of(url));
Integer warmUpSeconds = get(configObject, "warmUpSeconds");
bindConstant().annotatedWith(WarmUpSeconds.class).to(warmUpSeconds);
Integer maxHistoryItems = get(configObject, "maxHistoryItems");
bindConstant().annotatedWith(MaxHistoryItems.class).to(maxHistoryItems);
/***** email *****/
ConfigObject emailConfig = get(configObject, "email");
Boolean flag = get(emailConfig, "enabled");
if (flag) {
bindConstant().annotatedWith(EmailFrom.class).to((String) emailConfig.get("from"));
List toList = get(emailConfig, "to");
bind(new TypeLiteral>() {
//
}).annotatedWith(EmailTo.class).toInstance(toList);
ConfigObject smtpConfig = get(emailConfig, "smtp");
Boolean auth = (Boolean) smtpConfig.get("auth");
if (auth != null && auth) {
final String username = (String) smtpConfig.get("username");
final String password = (String) smtpConfig.get("password");
bind(Authenticator.class).toInstance(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
Boolean ssl = (Boolean) smtpConfig.remove("ssl");
String prefix;
String protocol;
if (ssl != null && ssl) {
protocol = "smtps";
prefix = "mail.smtps";
} else {
protocol = "smtp";
prefix = "mail.smtp";
}
Properties smtpProps = smtpConfig.toProperties(prefix);
smtpProps.setProperty("mail.transport.protocol", protocol);
bind(Properties.class).annotatedWith(SmtpProps.class).toInstance(smtpProps);
ConfigObject subjectConfig = get(emailConfig, "subjects");
Properties subjectProps = subjectConfig != null ? subjectConfig.toProperties() : new Properties();
bind(Properties.class).annotatedWith(SubjectProps.class).toInstance(subjectProps);
Integer maxEmailHistoryItems = get(emailConfig, "maxHistoryItems");
if (maxEmailHistoryItems == null) {
maxEmailHistoryItems = maxHistoryItems;
} else {
checkState(maxEmailHistoryItems <= maxHistoryItems,
"Max. history items in e-mail cannot be greater than global max history items");
}
bindConstant().annotatedWith(MaxEmailHistoryItems.class).to(maxEmailHistoryItems);
bind(EmailReporter.class);
} else {
bind(EmailReporter.class).toProvider(Providers.of(null));
}
/***** thread count *****/
Integer threadCount = get(configObject, "threadCount");
bind(ExecutorService.class).toInstance(Executors.newFixedThreadPool(threadCount));
/***** locale *****/
String localeString = get(configObject, "locale");
File localPropsFile = new File(destDir, ".config");
Properties localProps = new Properties();
if (localPropsFile.exists()) {
loadIntoProperties(localPropsFile, localProps);
String originalLocaleString = localProps.getProperty("locale");
if (!originalLocaleString.equals(localeString)) {
log.warn(
"Configured locale ({}) has changed but is ignored for compatibility reasons with comparison data. Locale used: {}",
localeString, originalLocaleString);
}
localeString = originalLocaleString;
} else {
localProps.setProperty("locale", localeString);
saveProperties(localPropsFile, localProps);
}
final Locale locale = new Locale(localeString);
bind(Locale.class).toInstance(locale);
/***** reports contents configuration *****/
Map> reportContentsConfigMap = get(configObject, "reportContents");
bind(new TypeLiteral
© 2015 - 2025 Weber Informatics LLC | Privacy Policy