Skip to content

add feature "rename fields by config" #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ JMeter ElasticSearch Backend Listener is a JMeter plugin enabling you to send te
* Filters
* Only send the samples you want by using Filters! Simply type them as follows in the field ``es.sample.filter`` : ``filter1;filter2;filter3`` or ``sampleLabel_must_contain_this``.
* You can also choose to exclude certain samplers; `!!exclude_this;filter1;filter2`
* Specific fields ```field1;field2;field3`
* Specific fields ``field1;field2;field3``
* Specify fields that you want to send to ElasticSearch (possible fields below)
* AllThreads
* BodySize
Expand All @@ -41,6 +41,9 @@ JMeter ElasticSearch Backend Listener is a JMeter plugin enabling you to send te
* SampleEndTime
* Timestamp
* InjectorHostname
* Field rename
* Set a different name for the predefined fields by providing a mapping in the field ``es.fields.mapping`` : ``AllThreads:threadCount;ResponseTime:duration;Timestamp:@timestamp``. In this case ``threadCount,duration,@timestamp``, would be sent to ElasticSearch instead of ``AllThreads,ResponseTime,Timestamp``.
* Use the changed name of fields when ``es.fields`` is used.
* Verbose, semi-verbose, error only, and quiet mode
* __debug__ : Send request/response information of all samplers (headers, body, etc.)
* __info__ : Sends all samplers to the ElasticSearch engine, but only sends the headers, body info for the failed samplers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ public class ElasticSearchMetric {
private int ciBuildNumber;
private HashMap<String, Object> json;
private Set<String> fields;
private Map<String,String> esFieldNameMap;
private boolean allReqHeaders;
private boolean allResHeaders;

public ElasticSearchMetric(
SampleResult sr, String testMode, String timeStamp, int buildNumber,
boolean parseReqHeaders, boolean parseResHeaders, Set<String> fields) {
boolean parseReqHeaders, boolean parseResHeaders, Set<String> fields, Map<String,String> fieldNameMap) {
this.sampleResult = sr;
this.esTestMode = testMode.trim();
this.esTimestamp = timeStamp.trim();
this.esFieldNameMap = fieldNameMap;
this.ciBuildNumber = buildNumber;
this.json = new HashMap<>();
this.allReqHeaders = parseReqHeaders;
Expand All @@ -56,28 +58,28 @@ public Map<String, Object> getMetric(BackendListenerContext context) throws Exce
SimpleDateFormat sdf = new SimpleDateFormat(this.esTimestamp);

//add all the default SampleResult parameters
addFilteredJSON("AllThreads", this.sampleResult.getAllThreads());
addFilteredJSON("BodySize", this.sampleResult.getBodySizeAsLong());
addFilteredJSON("Bytes", this.sampleResult.getBytesAsLong());
addFilteredJSON("SentBytes", this.sampleResult.getSentBytes());
addFilteredJSON("ConnectTime", this.sampleResult.getConnectTime());
addFilteredJSON("ContentType", this.sampleResult.getContentType());
addFilteredJSON("DataType", this.sampleResult.getDataType());
addFilteredJSON("ErrorCount", this.sampleResult.getErrorCount());
addFilteredJSON("GrpThreads", this.sampleResult.getGroupThreads());
addFilteredJSON("IdleTime", this.sampleResult.getIdleTime());
addFilteredJSON("Latency", this.sampleResult.getLatency());
addFilteredJSON("ResponseTime", this.sampleResult.getTime());
addFilteredJSON("SampleCount", this.sampleResult.getSampleCount());
addFilteredJSON("SampleLabel", this.sampleResult.getSampleLabel());
addFilteredJSON("ThreadName", this.sampleResult.getThreadName());
addFilteredJSON("URL", this.sampleResult.getURL());
addFilteredJSON("ResponseCode", this.sampleResult.getResponseCode());
addFilteredJSON("TestStartTime", JMeterContextService.getTestStartTime());
addFilteredJSON("SampleStartTime", sdf.format(new Date(this.sampleResult.getStartTime())));
addFilteredJSON("SampleEndTime", sdf.format(new Date(this.sampleResult.getEndTime())));
addFilteredJSON("Timestamp", this.sampleResult.getTimeStamp());
addFilteredJSON("InjectorHostname", InetAddress.getLocalHost().getHostName());
addFilteredJSON(this.esFieldNameMap.get("AllThreads"), this.sampleResult.getAllThreads());
addFilteredJSON(this.esFieldNameMap.get("BodySize"), this.sampleResult.getBodySizeAsLong());
addFilteredJSON(this.esFieldNameMap.get("Bytes"), this.sampleResult.getBytesAsLong());
addFilteredJSON(this.esFieldNameMap.get("SentBytes"), this.sampleResult.getSentBytes());
addFilteredJSON(this.esFieldNameMap.get("ConnectTime"), this.sampleResult.getConnectTime());
addFilteredJSON(this.esFieldNameMap.get("ContentType"), this.sampleResult.getContentType());
addFilteredJSON(this.esFieldNameMap.get("DataType"), this.sampleResult.getDataType());
addFilteredJSON(this.esFieldNameMap.get("ErrorCount"), this.sampleResult.getErrorCount());
addFilteredJSON(this.esFieldNameMap.get("GrpThreads"), this.sampleResult.getGroupThreads());
addFilteredJSON(this.esFieldNameMap.get("IdleTime"), this.sampleResult.getIdleTime());
addFilteredJSON(this.esFieldNameMap.get("Latency"), this.sampleResult.getLatency());
addFilteredJSON(this.esFieldNameMap.get("ResponseTime"), this.sampleResult.getTime());
addFilteredJSON(this.esFieldNameMap.get("SampleCount"), this.sampleResult.getSampleCount());
addFilteredJSON(this.esFieldNameMap.get("SampleLabel"), this.sampleResult.getSampleLabel());
addFilteredJSON(this.esFieldNameMap.get("ThreadName"), this.sampleResult.getThreadName());
addFilteredJSON(this.esFieldNameMap.get("URL"), this.sampleResult.getURL());
addFilteredJSON(this.esFieldNameMap.get("ResponseCode"), this.sampleResult.getResponseCode());
addFilteredJSON(this.esFieldNameMap.get("TestStartTime"), JMeterContextService.getTestStartTime());
addFilteredJSON(this.esFieldNameMap.get("SampleStartTime"), sdf.format(new Date(this.sampleResult.getStartTime())));
addFilteredJSON(this.esFieldNameMap.get("SampleEndTime"), sdf.format(new Date(this.sampleResult.getEndTime())));
addFilteredJSON(this.esFieldNameMap.get("Timestamp"), this.sampleResult.getTimeStamp());
addFilteredJSON(this.esFieldNameMap.get("InjectorHostname"), InetAddress.getLocalHost().getHostName());

// Add the details according to the mode that is set
switch (this.esTestMode) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.delirius325.jmeter.backendlistener.elasticsearch;
package io.github.delirius325.jmeter.backendlistener.elasticsearch;

import java.util.*;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -31,6 +31,7 @@ public class ElasticsearchBackendClient extends AbstractBackendListenerClient {
private static final String ES_PORT = "es.port";
private static final String ES_INDEX = "es.index";
private static final String ES_FIELDS = "es.fields";
private static final String ES_FIELDS_MAPPING = "es.fields.mapping";
private static final String ES_TIMESTAMP = "es.timestamp";
private static final String ES_BULK_SIZE = "es.bulk.size";
private static final String ES_TIMEOUT_MS = "es.timout.ms";
Expand Down Expand Up @@ -62,6 +63,7 @@ public class ElasticsearchBackendClient extends AbstractBackendListenerClient {
DEFAULT_ARGS.put(ES_TIMEOUT_MS, Long.toString(DEFAULT_TIMEOUT_MS));
DEFAULT_ARGS.put(ES_SAMPLE_FILTER, null);
DEFAULT_ARGS.put(ES_FIELDS, null);
DEFAULT_ARGS.put(ES_FIELDS_MAPPING, null);
DEFAULT_ARGS.put(ES_TEST_MODE, "info");
DEFAULT_ARGS.put(ES_AUTH_USER, "");
DEFAULT_ARGS.put(ES_AUTH_PWD, "");
Expand All @@ -78,6 +80,7 @@ public class ElasticsearchBackendClient extends AbstractBackendListenerClient {
private Set<String> modes;
private Set<String> filters;
private Set<String> fields;
private Map<String,String> fieldNameMap;
private int buildNumber;
private int bulkSize;
private int esVersion;
Expand All @@ -100,6 +103,7 @@ public void setupTest(BackendListenerContext context) throws Exception {
this.filters = new HashSet<>();
this.fields = new HashSet<>();
this.modes = new HashSet<>(Arrays.asList("info", "debug", "error", "quiet"));
this.fieldNameMap = new HashMap<String, String>();
this.bulkSize = Integer.parseInt(context.getParameter(ES_BULK_SIZE));
this.timeoutMs = Integer.parseInt((context.getParameter(ES_TIMEOUT_MS)));
this.buildNumber = (JMeterUtils.getProperty(ElasticsearchBackendClient.BUILD_NUMBER) != null
Expand Down Expand Up @@ -132,6 +136,7 @@ public void onFailure(Node node) {

convertParameterToSet(context, ES_SAMPLE_FILTER, this.filters);
convertParameterToSet(context, ES_FIELDS, this.fields);
convertParameterToMap(context, ES_FIELDS_MAPPING, this.fieldNameMap);

this.sender = new ElasticSearchMetricSender(client, context.getParameter(ES_INDEX).toLowerCase(),
context.getParameter(ES_AUTH_USER), context.getParameter(ES_AUTH_PWD),
Expand Down Expand Up @@ -164,6 +169,50 @@ private void convertParameterToSet(BackendListenerContext context, String parame
}
}

/**
* Method that converts a semicolon plus colon separated list contained in a parameter into a Map
* @param context
* @param parameter
* @param map
*/
private void convertParameterToMap(BackendListenerContext context, String parameter, Map<String,String> map) {
List<String> originalFieldnames = Arrays.asList(
"AllThreads",
"BodySize",
"Bytes",
"SentBytes",
"ConnectTime",
"ContentType",
"DataType",
"ErrorCount",
"GrpThreads",
"IdleTime",
"Latency",
"ResponseTime",
"SampleCount",
"SampleLabel",
"ThreadName",
"URL",
"ResponseCode",
"TestStartTime",
"SampleStartTime",
"SampleEndTime",
"Timestamp",
"InjectorHostname"
);
for (String field : originalFieldnames) {
map.put(field, field);
}
if (context.getParameter(parameter).contains(":")) {
for (String mapping : context.getParameter(parameter).split(";")) {
String[] m = mapping.split(":");
map.put(m[0].trim(), m[1].trim());
if(logger.isDebugEnabled())
logger.debug("fieldname '" + m[0].trim() + "' replaced by '" + m[1].trim() + "'");
}
}
}

/**
* Method that sets the SSL configuration to be able to send requests to a secured endpoint
* @param context
Expand Down Expand Up @@ -213,7 +262,7 @@ public void handleSampleResults(List<SampleResult> results, BackendListenerConte
ElasticSearchMetric metric = new ElasticSearchMetric(sr, context.getParameter(ES_TEST_MODE),
context.getParameter(ES_TIMESTAMP), this.buildNumber,
context.getBooleanParameter(ES_PARSE_REQ_HEADERS, false),
context.getBooleanParameter(ES_PARSE_RES_HEADERS, false), fields);
context.getBooleanParameter(ES_PARSE_RES_HEADERS, false), fields, this.fieldNameMap);

if (validateSample(context, sr)) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.HashMap;

import org.apache.jmeter.samplers.SampleResult;
import org.junit.Before;
Expand All @@ -18,9 +19,9 @@ public class TestElasticSearchBackend {
@Before
public void setUp() throws Exception {
metricCI = new ElasticSearchMetric(new SampleResult(), "info", "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", 1, false, false,
new HashSet<String>());
new HashSet<String>(), new HashMap<String, String>());
metricNoCI = new ElasticSearchMetric(new SampleResult(), "info", "yyyy-MM-dd'T'HH:mm:ss.SSSZZ", 0, false,
false, new HashSet<String>());
false, new HashSet<String>(), new HashMap<String, String>());
}

@Test
Expand Down