Skip to content

Commit

Permalink
Release XLT 8.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
jowerner committed Oct 7, 2024
2 parents 1ce179b + 3ff1ddc commit 616b5af
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 50 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.xceptance</groupId>
<artifactId>xlt</artifactId>
<version>8.4.0</version>
<version>8.4.1</version>
<packaging>jar</packaging>

<name>XLT</name>
Expand Down Expand Up @@ -322,7 +322,7 @@
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.4</version>
<version>1.5.5</version>
</dependency>
<dependency>
<!-- optional dependency of dnsjava, but XLT requires it -->
Expand Down
39 changes: 20 additions & 19 deletions src/main/java/com/xceptance/xlt/report/DataParserThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,25 @@ class DataParserThread implements Runnable
*/
private final ReportGeneratorConfiguration config;

/**
* The request processing rules for this thread. Each parser thread gets its own copy of the rule set. This way,
* there is no shared state between threads, hence we can more efficiently cache and process stuff.
*/
private final List<RequestProcessingRule> requestProcessingRules;

/**
* Constructor.
*
* @param dispatcher
* the dispatcher that coordinates result processing
* @param dataRecordFactory
* the data record factory
* @param fromTime
* the start time
* @param toTime
* the end time
* @param requestProcessingRules
* the request processing rules
* @param dispatcher
* the dispatcher that coordinates result processing
* @param removeIndexesFromRequestNames
* whether to automatically remove any indexes from request names
* @param config
* the report generator settings
*/
public DataParserThread(final Dispatcher dispatcher, final DataRecordFactory dataRecordFactory, final long fromTime, final long toTime,
final ReportGeneratorConfiguration config)
Expand All @@ -104,6 +108,8 @@ public DataParserThread(final Dispatcher dispatcher, final DataRecordFactory dat
this.toTime = toTime;
this.dispatcher = dispatcher;
this.config = config;

requestProcessingRules = config.getRequestProcessingRules();
}

/**
Expand All @@ -112,9 +118,6 @@ public DataParserThread(final Dispatcher dispatcher, final DataRecordFactory dat
@Override
public void run()
{
// each parser gets its own rules. They are all identical, but don't share state, hence we can more
// efficiently cache and process
final List<RequestProcessingRule> requestProcessingRules = config.getRequestProcessingRules();
final boolean removeIndexes = config.getRemoveIndexesFromRequestNames();

final double SAMPLELIMIT = 1 / ((double) config.dataSampleFactor);
Expand Down Expand Up @@ -218,7 +221,8 @@ public void run()
}
catch (final Exception ex)
{
final String msg = String.format("Failed to parse data record at line %,d in file '%s': %s\nLine is: ", lineNumber, file, ex, lines.get(i).toString());
final String msg = String.format("Failed to parse data record at line %,d in file '%s': %s\nLine is: ", lineNumber,
file, ex, lines.get(i).toString());
LOG.error(msg, ex);

continue;
Expand Down Expand Up @@ -295,16 +299,14 @@ else if (adjustTimerName && (data instanceof RequestData || data instanceof Page
* discarding requests.
*
* @param requestData
* the request data record
* the request data record
* @param requestProcessingRules
* the rules to apply
* the rules to apply
* @param removeIndexesFromRequestNames
* in case we want to clean the name too
*
* in case we want to clean the name too
* @return the processed request data record, or <code>null</code> if the data record is to be discarded
*/
private RequestData postprocess(final RequestData requestData,
final List<RequestProcessingRule> requestProcessingRules,
private RequestData postprocess(final RequestData requestData, final List<RequestProcessingRule> requestProcessingRules,
final boolean removeIndexesFromRequestNames)
{
// fix up the name first (Product.1.2 -> Product) if so configured
Expand Down Expand Up @@ -356,12 +358,11 @@ else if (state == ReturnState.STOP)
}
}

// ok, we processed all rules for this dataset, get us the final hashcode for the name, because we need that later
// ok, we processed all rules for this dataset, get us the final hashcode for the name, because we need that
// later
// here the cache is likely still hot, so this is less expensive
requestData.getName().hashCode();

return requestData;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import com.xceptance.xlt.api.report.ReportProvider;
import com.xceptance.xlt.api.report.ReportProviderConfiguration;
import com.xceptance.xlt.api.util.XltException;
import com.xceptance.xlt.api.util.XltLogger;
import com.xceptance.xlt.api.util.XltProperties;
import com.xceptance.xlt.common.XltConstants;
import com.xceptance.xlt.common.XltPropertyNames;
Expand Down Expand Up @@ -79,26 +78,26 @@ public static class ChartCappingInfo
*/
public enum ChartCappingMethod
{
/** No capping (default). */
NONE,
/** No capping (default). */
NONE,

/** Cap at an absolute value. */
ABSOLUTE,
/** Cap at an absolute value. */
ABSOLUTE,

/** Cap at the n-fold of the average value. */
NFOLD_OF_AVERAGE
/** Cap at the n-fold of the average value. */
NFOLD_OF_AVERAGE
};

/**
* The supported capping modes.
*/
public enum ChartCappingMode
{
/** Cap the chart at the capping value only if necessary. */
SMART,
/** Cap the chart at the capping value only if necessary. */
SMART,

/** Always cap the chart at the capping value even if the maximum values are below the capping value. */
ALWAYS
/** Always cap the chart at the capping value even if the maximum values are below the capping value. */
ALWAYS
};

/**
Expand Down Expand Up @@ -163,9 +162,13 @@ public enum ChartCappingMode

// Special settings for profiling and debugging
private static final String PROP_PARSER_THREAD_COUNT = PROP_PREFIX + "parser.threads";

private static final String PROP_READER_THREAD_COUNT = PROP_PREFIX + "reader.threads";

private static final String PROP_THREAD_QUEUE_SIZE = PROP_PREFIX + "queue.bucketsize";

private static final String PROP_THREAD_QUEUE_LENGTH = PROP_PREFIX + "queue.length";

private static final String PROP_DATA_SAMPLE_FACTOR = PROP_PREFIX + "data.sampleFactor";

private static final String PROP_TRANSFORMATIONS_PREFIX = PROP_PREFIX + "transformations.";
Expand Down Expand Up @@ -243,8 +246,11 @@ public enum ChartCappingMode
private boolean noAgentCharts;

public final int readerThreadCount;

public final int parserThreadCount;

public final int threadQueueBucketSize;

public final int threadQueueLength;

public final int dataSampleFactor;
Expand Down Expand Up @@ -276,11 +282,11 @@ public enum ChartCappingMode
private final int transactionErrorOverviewChartLimit;

private final int errorDetailsChartLimit;

private final int directoryLimitPerError;

private final double directoryReplacementChance;

private final int stackTracesLimit;

private final Map<Pattern, Double> apdexThresholdsByActionNamePattern = new HashMap<>();
Expand Down Expand Up @@ -408,9 +414,9 @@ public ReportGeneratorConfiguration(Properties xltProperties, final File overrid

directoryLimitPerError = getIntProperty(XltPropertyNames.ReportGenerator.Errors.DIRECTORY_LIMIT_PER_ERROR, 10);
directoryReplacementChance = getDoubleProperty(XltPropertyNames.ReportGenerator.Errors.DIRECTORY_REPLACEMENT_CHANCE, 0.1);

stackTracesLimit = getIntProperty(XltPropertyNames.ReportGenerator.Errors.STACKTRACES_LIMIT, 500);

// event settings
groupEventsByTestCase = getBooleanProperty(PROP_PREFIX + "events.groupByTestCase", true);
eventLimit = getIntProperty(PROP_PREFIX + "events.eventLimit", 100);
Expand Down Expand Up @@ -483,7 +489,7 @@ private void checkForLeadingZeros(final String s)
}
sb.append("\n");

throw new RuntimeException(sb.toString());
throw new XltException(sb.toString());
}
}

Expand Down Expand Up @@ -791,7 +797,7 @@ public int getErrorDetailsChartLimit()
{
return errorDetailsChartLimit;
}

/**
* The maximum number of directory hints remembered for a certain error (stack trace).
*
Expand All @@ -801,17 +807,18 @@ public int getDirectoryLimitPerError()
{
return directoryLimitPerError;
}

/**
* The chance to replace directory hints remembered for a certain error (stack trace) when the maximum number is reached.
* The chance to replace directory hints remembered for a certain error (stack trace) when the maximum number is
* reached.
*
* @return the chance to replace listed directory hints
*/
public double getDirectoryReplacementChance()
{
return directoryReplacementChance;
}

/**
* The maximum number of errors that will be saved complete with their stack trace.
*
Expand Down Expand Up @@ -1001,7 +1008,6 @@ public int getEventLimitPerTestCase()
return eventLimit;
}


/**
* Indicates whether or not to group events by test case.
*
Expand All @@ -1012,7 +1018,6 @@ public int getEventMessageLimitPerEvent()
return eventMessageLimit;
}


/**
* Returns whether to automatically remove any indexes from the request name (i.e. "HomePage.1.27" -> "HomePage").
*
Expand Down Expand Up @@ -1491,15 +1496,15 @@ public List<RequestProcessingRule> getRequestProcessingRules()
// ensure that either newName or dropOnMatch is set
if (StringUtils.isNotBlank(newName) == dropOnMatch)
{
throw new RuntimeException(String.format("Either specify property '%s' or set property '%s' to true",
basePropertyName + ".newName", basePropertyName + ".dropOnMatch"));
throw new XltException(String.format("Either specify property '%s' or set property '%s' to true",
basePropertyName + ".newName", basePropertyName + ".dropOnMatch"));
}

// ensure that dropOnMatch and stopOnMatch are not contradicting
if (dropOnMatch && !stopOnMatch)
{
throw new RuntimeException(String.format("If property '%s' is true, property '%s' cannot be false",
basePropertyName + ".dropOnMatch", basePropertyName + ".stopOnMatch"));
throw new XltException(String.format("If property '%s' is true, property '%s' cannot be false",
basePropertyName + ".dropOnMatch", basePropertyName + ".stopOnMatch"));
}

// create and validate the rules
Expand All @@ -1518,7 +1523,6 @@ public List<RequestProcessingRule> getRequestProcessingRules()
{
// Log it and continue with next rule.
final String errMsg = "Request processing rule '" + basePropertyName + "' is invalid. " + imre.getMessage();
XltLogger.reportLogger.error(errMsg, imre);
System.err.println(errMsg);
// remember that we encountered an invalid merge rule
invalidRulePresent = true;
Expand All @@ -1527,7 +1531,7 @@ public List<RequestProcessingRule> getRequestProcessingRules()

if (invalidRulePresent)
{
throw new RuntimeException("Please check your configuration. At least one request processing rule is invalid and needs to be fixed.");
throw new XltException("Please check your configuration. At least one request processing rule is invalid and needs to be fixed.");
}

return requestProcessingRules;
Expand Down

0 comments on commit 616b5af

Please sign in to comment.