Author: sebb
Date: Thu Dec 6 15:25:13 2007
New Revision: 601911
URL: http://svn.apache.org/viewvc?rev=601911&view=rev
Log:
Can specify list of variable names to be written to JTL files (CSV and XML
format)
Modified:
jakarta/jmeter/trunk/bin/jmeter.properties
jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/TransactionController.java
jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java
jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/CSVSaveService.java
jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/converters/SampleResultConverter.java
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
jakarta/jmeter/trunk/xdocs/changes.xml
jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
jakarta/jmeter/trunk/xdocs/usermanual/listeners.xml
Modified: jakarta/jmeter/trunk/bin/jmeter.properties
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/bin/jmeter.properties?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
--- jakarta/jmeter/trunk/bin/jmeter.properties (original)
+++ jakarta/jmeter/trunk/bin/jmeter.properties Thu Dec 6 15:25:13 2007
@@ -321,6 +321,12 @@
#jmeter.save.saveservice.default_delimiter=\t
#jmeter.save.saveservice.print_field_names=false
+# Optional list of JMeter variable names whose values are to be saved in the
result data files.
+# Use commas to separate the names. For example:
+#sample_variables=SESSION_ID,REFERENCE
+# N.B. The current implementation saves the values in XML as attributes,
+# so the names must be valid XML names.
+
# Optional xml processing instruction for line 2 of the file:
#jmeter.save.saveservice.xml_pi=<?xml-stylesheet type="text/xsl"
href="../extras/jmeter-results-detail-report_21.xsl"?>
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/TransactionController.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/TransactionController.java?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/TransactionController.java
(original)
+++
jakarta/jmeter/trunk/src/core/org/apache/jmeter/control/TransactionController.java
Thu Dec 6 15:25:13 2007
@@ -170,7 +170,7 @@
if (pack == null) {
log.warn("Could not fetch
SamplePackage");
} else {
- SampleEvent event = new SampleEvent(res,
threadContext.getThreadGroup().getName());
+ SampleEvent event = new SampleEvent(res,
threadContext.getThreadGroup().getName(),threadVars);
// We must set res to null now, before sending the event
for the transaction,
// so that we can ignore that event in our sampleOccured
method
res = null;
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java
(original)
+++
jakarta/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleSaveConfiguration.java
Thu Dec 6 15:25:13 2007
@@ -59,7 +59,7 @@
*
*/
public class SampleSaveConfiguration implements Cloneable, Serializable {
- private static final long serialVersionUID = 6L;
+ private static final long serialVersionUID = 7L;
// ---------------------------------------------------------------------
// PROPERTY FILE CONSTANTS
@@ -384,7 +384,19 @@
// Don't save this, as not settable via GUI
private String delimiter = _delimiter;
+
+ // Don't save this - only needed for processing CSV headers currently
+ private transient int varCount = 0;
+
private static final SampleSaveConfiguration _static = new
SampleSaveConfiguration();
+
+ public int getVarCount() { // Only for use by CSVSaveService
+ return varCount;
+ }
+
+ public void setVarCount(int varCount) { // Only for use by
CSVSaveService
+ this.varCount = varCount;
+ }
// Give access to initial configuration
public static SampleSaveConfiguration staticConfig() {
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/CSVSaveService.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/CSVSaveService.java?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/CSVSaveService.java
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/CSVSaveService.java
Thu Dec 6 15:25:13 2007
@@ -86,7 +86,10 @@
private static final String CSV_LATENCY = "Latency"; // $NON-NLS-1$
private static final String CSV_ENCODING = "Encoding"; // $NON-NLS-1$
private static final String CSV_HOSTNAME = "Hostname"; // $NON-NLS-1$
-
+
+ // Used to enclose variable name labels, to distinguish from any of the
above labels
+ private static final String VARIABLE_NAME_QUOTE_CHAR = "\""; //
$NON-NLS-1$
+
// Initial config from properties
static private final SampleSaveConfiguration _saveConfig =
SampleSaveConfiguration.staticConfig();
@@ -120,6 +123,7 @@
long lineNumber=1;
SampleSaveConfiguration saveConfig =
CSVSaveService.getSampleSaveConfiguration(line,filename);
if (saveConfig == null) {// not a valid header
+ log.info(filename+" does not appear to have a
valid header. Using default configuration.");
saveConfig = (SampleSaveConfiguration)
resultCollector.getSaveConfig().clone(); // may change the format later
dataReader.reset(); // restart from beginning
lineNumber = 0;
@@ -148,7 +152,7 @@
* @param lineNumber - line number for error reporting
* @return SampleResult
*
- * @deprecated Does not handle quoted strings
+ * @deprecated Does not handle quoted strings; use [EMAIL PROTECTED]
#processSamples(String, Visualizer, ResultCollector)} instead
*
* @throws JMeterError
*/
@@ -174,7 +178,7 @@
*
* @throws JMeterError
*/
- public static SampleEvent makeResultFromDelimitedString(
+ private static SampleEvent makeResultFromDelimitedString(
final String[] parts,
final SampleSaveConfiguration saveConfig, // may be updated
final long lineNumber) {
@@ -315,6 +319,10 @@
hostname = parts[i++];
}
+ if (i + saveConfig.getVarCount() < parts.length){
+ log.warn("Line: "+lineNumber+". Found "+parts.length+" fields,
expected "+i+". Extra fields have been ignored.");
+ }
+
} catch (NumberFormatException e) {
log.warn("Error parsing field '" + field + "' at line "
+ lineNumber + " " + e);
throw new JMeterError(e);
@@ -435,6 +443,13 @@
text.append(delim);
}
+ for (int i = 0; i < SampleEvent.getVarCount(); i++){
+ text.append(VARIABLE_NAME_QUOTE_CHAR);
+ text.append(SampleEvent.getVarName(i));
+ text.append(VARIABLE_NAME_QUOTE_CHAR);
+ text.append(delim);
+ }
+
String resultString = null;
int size = text.length();
int delSize = delim.length();
@@ -496,7 +511,8 @@
// word followed by 0 or more repeats of (non-word char
+ word)
// where the non-word char (\2) is the same
// e.g. abc|def|ghi but not abd|def~ghi
- .getPattern("\\w+((\\W)\\w+)?(\\2\\w+)*", //
$NON-NLS-1$
+
.getPattern("\\w+((\\W)\\w+)?(\\2\\w+)*(\\2\"\\w+\")*", // $NON-NLS-1$
+ // last entries may be quoted
strings
Perl5Compiler.READ_ONLY_MASK);
if (matcher.matches(input, pattern)) {
delim = matcher.getMatch().group(2);
@@ -511,15 +527,24 @@
// We know the column names all exist, so create the config
SampleSaveConfiguration saveConfig=new
SampleSaveConfiguration(false);
+ int varCount = 0;
for(int i=0;i<parts.length;i++){
- Functor set = (Functor)
headerLabelMethods.get(parts[i]);
- set.invoke(saveConfig,new Boolean[]{Boolean.TRUE});
+ String label = parts[i];
+ if (isVariableName(label)){
+ varCount++;
+ } else {
+ Functor set = (Functor)
headerLabelMethods.get(label);
+ set.invoke(saveConfig,new
Boolean[]{Boolean.TRUE});
+ }
}
if (delim != null){
log.warn("Default delimiter
'"+_saveConfig.getDelimiter()+"' did not work; using alternate '"+delim+"' for
reading "+filename);
saveConfig.setDelimiter(delim);
}
+
+ saveConfig.setVarCount(varCount);
+
return saveConfig;
}
@@ -529,6 +554,11 @@
// Check if the line is a header
for(int i=0;i<parts.length;i++){
final String label = parts[i];
+ // Check for Quoted variable names
+ if (isVariableName(label)){
+ previous=Integer.MAX_VALUE; // they are always
last
+ continue;
+ }
int current = headerLabelMethods.indexOf(label);
if (current == -1){
return null; // unknown column name
@@ -543,6 +573,18 @@
}
/**
+ * Check if the label is a variable name, i.e. is it enclosed in
double-quotes?
+ *
+ * @param label column name from CSV file
+ * @return if the label is enclosed in double-quotes
+ */
+ private static boolean isVariableName(final String label) {
+ return label.length() > 2
+ && label.startsWith(VARIABLE_NAME_QUOTE_CHAR)
+ && label.endsWith(VARIABLE_NAME_QUOTE_CHAR);
+ }
+
+ /**
* Method will save aggregate statistics as CSV. For now I put it here.
* Not sure if it should go in the newer SaveService instead of here.
* if we ever decide to get rid of this class, we'll need to move this
@@ -613,6 +655,7 @@
// These methods handle parameters that could contain
delimiters or escapes:
public void append(String s){
addDelim();
+ //if (s == null) return;
sb.append(escapeDelimiters(s,specials));
}
public void append(Object obj){
@@ -730,6 +773,10 @@
if (saveConfig.saveHostname()) {
text.append(event.getHostname());
+ }
+
+ for (int i=0; i < SampleEvent.getVarCount(); i++){
+ text.append(event.getVarValue(i));
}
return text.toString();
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/converters/SampleResultConverter.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/converters/SampleResultConverter.java?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
---
jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/converters/SampleResultConverter.java
(original)
+++
jakarta/jmeter/trunk/src/core/org/apache/jmeter/save/converters/SampleResultConverter.java
Thu Dec 6 15:25:13 2007
@@ -265,11 +265,16 @@
writer.addAttribute(ATT_GRP_THRDS,
String.valueOf(res.getGroupThreads()));
writer.addAttribute(ATT_ALL_THRDS,
String.valueOf(res.getAllThreads()));
}
+ SampleEvent event = (SampleEvent)
context.get(SaveService.SAMPLE_EVENT_OBJECT);
if (save.saveHostname()){
- SampleEvent event = (SampleEvent)
context.get(SaveService.SAMPLE_EVENT_OBJECT);
if (event != null) {
writer.addAttribute(ATT_HOSTNAME, event.getHostname());
}
+ }
+ if (event != null) {
+ for (int i = 0; i < SampleEvent.getVarCount(); i++){
+ writer.addAttribute(SampleEvent.getVarName(i),
ConversionHelp.encode(event.getVarValue(i)));
+ }
}
}
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
(original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
Thu Dec 6 15:25:13 2007
@@ -286,9 +286,8 @@
// Get the sampler ready to sample
SamplePackage pack =
compiler.configureSampler(sam);
- // Hack: save the package
for any transaction
- // controllers
-
threadContext.getVariables().putObject(PACKAGE_OBJECT, pack);
+ // Hack: save the package
for any transaction controllers
+
threadVars.putObject(PACKAGE_OBJECT, pack);
delay(pack.getTimers());
Sampler sampler = pack.getSampler();
@@ -572,7 +571,7 @@
}
private void notifyListeners(List listeners, SampleResult result) {
- SampleEvent event = new SampleEvent(result,
threadGroup.getName());
+ SampleEvent event = new SampleEvent(result,
threadGroup.getName(), threadVars);
notifier.notifyListeners(event, listeners);
}
Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Thu Dec 6 15:25:13 2007
@@ -63,6 +63,7 @@
<li>Reduce class loading in non-GUI mode by only looking for Functions in
class names
that contain '.functions.' and don't contain '.gui.'</li>
<li>Bug 43379 - Switch Controller now supports selection by name as well as
number</li>
+<li>Can specify list of variable names to be written to JTL files (CSV and XML
format)</li>
</ul>
<h4>Non-functional changes</h4>
Modified: jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/component_reference.xml Thu Dec 6
15:25:13 2007
@@ -1696,6 +1696,10 @@
</ul>
<p>To minimise the amount of memory needed, use the Simple Data Writer, and
use the CSV format.</p>
<p>
+<note>
+Versions of JMeter after 2.3.1 allow JMeter variables to be saved to the
output files.
+This can only be specified using a property. See the following link for
details.
+</note>
For full details on setting up the default items to be saved
see the <a href="listeners.html#defaults">Listener Default Configuration</a>
documentation.
For details of the contents of the output files,
Modified: jakarta/jmeter/trunk/xdocs/usermanual/listeners.xml
URL:
http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/usermanual/listeners.xml?rev=601911&r1=601910&r2=601911&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/usermanual/listeners.xml (original)
+++ jakarta/jmeter/trunk/xdocs/usermanual/listeners.xml Thu Dec 6 15:25:13 2007
@@ -165,17 +165,29 @@
#jmeter.save.saveservice.print_field_names=false
+# Optional list of JMeter variable names whose values are to be saved in the
result data files.
+# Use commas to separate the names. For example:
+#sample_variables=SESSION_ID,REFERENCE
+# N.B. The current implementation saves the values in XML as attributes,
+# so the names must be valid XML names.
+
# Optional xml processing instruction for line 2 of the file:
#jmeter.save.saveservice.xml_pi=&lt;?xml-stylesheet type="text/xsl"
href="sample.xsl"?>
</pre>
</code></p>
<p>
-The date format to be used for the timestamp_format is described in <A
+The date format to be used for the timestamp_format is described in <a
HREF="http://java.sun.com/j2se/1.4/docs/api/java/text/SimpleDateFormat.html">
-<B>SimpleDateFormat</B></A>.
+<b>SimpleDateFormat</b></a>.
Bear in mind that choosing a date format other than "ms" is likely to
make it impossible for JMeter to interpret the value when it is read
in later for viewing purposes.</p>
+<p>
+Versions of JMeter after 2.3.1 allow one to use the <b>sample_variables</b>
+property to define a list of additional JMeter variables which are to be saved
with
+each sample in the JTL files. The values are written to CSV files as
additional columns,
+and as additional attributes in XML files.
+</p>
</section>
<section name="§-num;.2 non-GUI (batch) test runs" anchor="batch">
@@ -197,6 +209,12 @@
This file is recreated each time, so if you want to keep the log files for
each run,
you will need to rename it using the -j option as above. The -j option was
added in version 2.3.
</p>
+<p>Versions of JMeter after 2.3.1 support variables in the log file name.
+If the filename contains paired single-quotes, then the name is processed
+as a SimpleDateFormat format applied to the current date, for example:
+<b>log_file='jmeter_'yyyyMMddHHmmss'.tmp'</b>.
+This can be used to generate a unique name for each test run.
+</p>
</section>
<section name="§-num;.3 Resource usage" anchor="resources">
@@ -240,6 +258,7 @@
<li>SampleCount - number of samples (1, unless multiple samples are
aggregated)</li>
<li>ErrorCount - number of errors (0 or 1, unless multiple samples are
aggregated)</li>
<li>Hostname where the sample was generated</li>
+<li>Variables, if specified</li>
</ul>
</section>
@@ -391,11 +410,17 @@
<tr><td> t</td><td>Elapsed time (milliseconds)</td></tr>
<tr><td>tn</td><td>Thread Name</td></tr>
<tr><td>ts</td><td>timeStamp (milliseconds since midnight Jan 1, 1970
UTC)</td></tr>
+<tr><td>varname</td><td>Value of the named variable (versions of JMeter after
2.3.1)</td></tr>
</table>
<p>
Versions 2.1 and 2.1.1 of JMeter saved the Response Code as "rs", but read it
back expecting to find "rc".
This has been corrected so that it is always saved as "rc"; either "rc" or
"rs" can be read.
</p>
+<note>
+Versions of JMeter after 2.3.1 allow additional variables to be saved with the
test plan.
+Currently, the variables are saved as additional attributes.
+The testplan variable name is used as the attribute name.
+</note>
</section>
<section name="§-num;.8 Saving response data" anchor="saving">
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]