Skip to content

Commit ac7e878

Browse files
committed
Fixed ElapsedTime value. Added elasticsearch index template. Added Kibana visualization.
1 parent 33b9a3c commit ac7e878

File tree

4 files changed

+315
-6
lines changed

4 files changed

+315
-6
lines changed
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Elasticsearch index template
2+
3+
Below are instructions to create an Elasticsearch template for the index that will be used to store JMeter metrics:
4+
5+
```text
6+
HEAD _template/jmeter_metrics_template
7+
GET /_template/jmeter_metrics_template
8+
GET _template/*jmeter_metrics*
9+
DELETE /_template/jmeter_metrics_template
10+
11+
PUT _template/jmeter_metrics_template
12+
{
13+
"order": 1,
14+
"template": "jmeter_metrics-*",
15+
"settings": {
16+
"index": {
17+
"codec": "best_compression",
18+
"mapping": {
19+
"total_fields": {
20+
"limit": "256"
21+
}
22+
},
23+
"refresh_interval": "1s",
24+
"number_of_replicas": "2",
25+
"number_of_shards": "1"
26+
}
27+
},
28+
"mappings": {
29+
"logs": {
30+
"dynamic_templates": [
31+
{
32+
"strings_as_keywords": {
33+
"match_mapping_type": "string",
34+
"mapping": {
35+
"type": "keyword"
36+
}
37+
}
38+
}
39+
],
40+
"_all": {
41+
"enabled": false
42+
},
43+
"properties": {
44+
"@timestamp": {
45+
"type": "date"
46+
},
47+
"@version": {
48+
"type": "keyword",
49+
"ignore_above": 256
50+
},
51+
"AllThreads": {
52+
"type": "integer"
53+
},
54+
"AssertionResults": {
55+
"type": "text"
56+
},
57+
"BodySize": {
58+
"type": "long"
59+
},
60+
"BuildNumber": {
61+
"type": "integer"
62+
},
63+
"Bytes": {
64+
"type": "long"
65+
},
66+
"ConnectTime": {
67+
"type": "long"
68+
},
69+
"ContentType": {
70+
"type": "text",
71+
"fields": {
72+
"keyword": {
73+
"type": "keyword",
74+
"ignore_above": 256
75+
}
76+
}
77+
},
78+
"DataType": {
79+
"type": "keyword",
80+
"ignore_above": 256
81+
},
82+
"ElapsedTime": {
83+
"type": "date"
84+
},
85+
"ElapsedTimeComparison": {
86+
"type": "date"
87+
},
88+
"ErrorCount": {
89+
"type": "integer"
90+
},
91+
"FailureMessage": {
92+
"type": "text"
93+
},
94+
"GrpThreads": {
95+
"type": "integer"
96+
},
97+
"IdleTime": {
98+
"type": "long"
99+
},
100+
"InjectorHostname": {
101+
"type": "keyword",
102+
"ignore_above": 256
103+
},
104+
"Latency": {
105+
"type": "long"
106+
},
107+
"RequestBody": {
108+
"type": "text"
109+
},
110+
"RequestHeaders": {
111+
"type": "text"
112+
},
113+
"ResponseBody": {
114+
"type": "text"
115+
},
116+
"ResponseCode": {
117+
"type": "keyword",
118+
"ignore_above": 256
119+
},
120+
"ResponseHeaders": {
121+
"type": "text"
122+
},
123+
"ResponseMessage": {
124+
"type": "text"
125+
},
126+
"ResponseTime": {
127+
"type": "long"
128+
},
129+
"SampleCount": {
130+
"type": "integer"
131+
},
132+
"SampleEndTime": {
133+
"type": "date"
134+
},
135+
"SampleLabel": {
136+
"type": "keyword",
137+
"ignore_above": 256
138+
},
139+
"SampleStartTime": {
140+
"type": "date"
141+
},
142+
"SentBytes": {
143+
"type": "long"
144+
},
145+
"Success": {
146+
"type": "boolean"
147+
},
148+
"TestElement": {
149+
"properties": {
150+
"name": {
151+
"type": "keyword",
152+
"ignore_above": 256
153+
}
154+
}
155+
},
156+
"TestStartTime": {
157+
"type": "long"
158+
},
159+
"ThreadName": {
160+
"type": "keyword",
161+
"ignore_above": 256
162+
},
163+
"Timestamp": {
164+
"type": "date"
165+
},
166+
"URL": {
167+
"type": "keyword",
168+
"ignore_above": 256
169+
}
170+
}
171+
}
172+
},
173+
"aliases": {
174+
"jmeter_metrics": {}
175+
}
176+
}
177+
178+
DELETE jmeter_metrics-2019-06-28
179+
PUT jmeter_metrics-2019-06-28
180+
GET jmeter_metrics-2019-06-28/_mapping
181+
GET jmeter_metrics-2019-06-28/_aliases
182+
GET jmeter_metrics-2019-06-28/_settings
183+
```

docs/Listener visualization.json

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
[
2+
{
3+
"_id": "JMeter_statistic_dashboard",
4+
"_type": "dashboard",
5+
"_source": {
6+
"title": "JMeter statistic",
7+
"hits": 0,
8+
"description": "",
9+
"panelsJSON": "[{\"panelIndex\":\"5\",\"gridData\":{\"x\":0,\"y\":4,\"w\":12,\"h\":4,\"i\":\"5\"},\"embeddableConfig\":{},\"id\":\"Aggregate_report_visualization\",\"type\":\"visualization\",\"version\":\"6.4.0\"},{\"panelIndex\":\"6\",\"gridData\":{\"x\":4,\"y\":1,\"w\":8,\"h\":3,\"i\":\"6\"},\"embeddableConfig\":{\"vis\":{\"legendOpen\":false}},\"id\":\"TPS_visualization\",\"type\":\"visualization\",\"version\":\"6.4.0\"},{\"panelIndex\":\"7\",\"gridData\":{\"x\":0,\"y\":1,\"w\":4,\"h\":3,\"i\":\"7\"},\"embeddableConfig\":{\"vis\":{\"defaultColors\":{\"0 - 500\":\"rgb(165,0,38)\",\"1000 - 5000\":\"rgb(0,104,55)\",\"500 - 1000\":\"rgb(255,255,190)\"},\"legendOpen\":false}},\"id\":\"Intensity_visualization\",\"type\":\"visualization\",\"version\":\"6.4.0\"},{\"panelIndex\":\"8\",\"gridData\":{\"x\":0,\"y\":0,\"w\":12,\"h\":1,\"i\":\"8\"},\"version\":\"6.2.4\",\"type\":\"visualization\",\"id\":\"Controls_visualization\"}]",
10+
"optionsJSON": "{\"darkTheme\":false,\"hidePanelTitles\":true,\"useMargins\":false}",
11+
"version": 1,
12+
"timeRestore": false,
13+
"kibanaSavedObjectMeta": {
14+
"searchSourceJSON": "{\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[],\"highlightAll\":true,\"version\":true}"
15+
}
16+
},
17+
"_meta": {
18+
"savedObjectVersion": 1
19+
}
20+
},
21+
{
22+
"_id": "Intensity_visualization",
23+
"_type": "visualization",
24+
"_source": {
25+
"title": "Intensity",
26+
"visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{\"customBucket\":{\"enabled\":true,\"id\":\"1-bucket\",\"params\":{\"customInterval\":\"30s\",\"extended_bounds\":{},\"field\":\"Timestamp\",\"interval\":\"m\",\"min_doc_count\":1},\"schema\":{\"aggFilter\":[],\"deprecate\":false,\"editor\":false,\"group\":\"none\",\"max\":null,\"min\":0,\"name\":\"bucketAgg\",\"params\":[],\"title\":\"Bucket Agg\"},\"type\":\"date_histogram\"},\"customLabel\":\"TPS\",\"customMetric\":{\"enabled\":true,\"id\":\"1-metric\",\"params\":{\"field\":\"SampleCount\",\"json\":\"{ \\\"script\\\" : \\\"_value/60\\\" }\"},\"schema\":{\"aggFilter\":[\"!top_hits\",\"!percentiles\",\"!percentile_ranks\",\"!median\",\"!std_dev\",\"!sum_bucket\",\"!avg_bucket\",\"!min_bucket\",\"!max_bucket\",\"!derivative\",\"!moving_avg\",\"!serial_diff\",\"!cumulative_sum\"],\"deprecate\":false,\"editor\":false,\"group\":\"none\",\"max\":null,\"min\":0,\"name\":\"metricAgg\",\"params\":[],\"title\":\"Metric Agg\"},\"type\":\"sum\"}},\"schema\":\"metric\",\"type\":\"avg_bucket\"}],\"params\":{\"addLegend\":true,\"addTooltip\":true,\"gauge\":{\"backStyle\":\"Full\",\"colorSchema\":\"Green to Red\",\"colorsRange\":[{\"from\":0,\"to\":500},{\"from\":500,\"to\":1000},{\"from\":1000,\"to\":5000}],\"extendRange\":true,\"gaugeColorMode\":\"Labels\",\"gaugeStyle\":\"Full\",\"gaugeType\":\"Arc\",\"invertColors\":true,\"labels\":{\"color\":\"black\",\"show\":true},\"orientation\":\"vertical\",\"percentageMode\":false,\"scale\":{\"color\":\"#333\",\"labels\":false,\"show\":true},\"style\":{\"bgColor\":false,\"bgFill\":\"#eee\",\"bgMask\":false,\"bgWidth\":0.9,\"fontSize\":60,\"labelColor\":true,\"mask\":false,\"maskBars\":50,\"subText\":\"\",\"width\":0.9},\"type\":\"meter\",\"verticalSplit\":false},\"isDisplayWarning\":false,\"type\":\"gauge\"},\"title\":\"Intensity\",\"type\":\"gauge\"}",
27+
"uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0 - 500\":\"rgb(165,0,38)\",\"500 - 1000\":\"rgb(255,255,190)\",\"1000 - 5000\":\"rgb(0,104,55)\"}}}",
28+
"description": "",
29+
"version": 1,
30+
"kibanaSavedObjectMeta": {
31+
"searchSourceJSON": "{\"index\":\"jmeter_metrics\",\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}"
32+
}
33+
},
34+
"_meta": {
35+
"savedObjectVersion": 1
36+
}
37+
},
38+
{
39+
"_id": "TPS_visualization",
40+
"_type": "visualization",
41+
"_source": {
42+
"title": "TPS",
43+
"visState": "{\"title\":\"TPS\",\"type\":\"area\",\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":true,\"style\":{\"color\":\"#eee\"},\"valueAxis\":\"ValueAxis-1\"},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"RightAxis-1\",\"type\":\"value\",\"position\":\"right\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"silhouette\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"TPS\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"histogram\",\"mode\":\"normal\",\"data\":{\"label\":\"TPS\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"SampleCount\",\"json\":\"{ \\\"script\\\" : \\\"_value/60\\\" }\",\"customLabel\":\"TPS\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"Timestamp\",\"interval\":\"m\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{},\"customLabel\":\".\"}}]}",
44+
"uiStateJSON": "{\"vis\":{\"legendOpen\":false}}",
45+
"description": "",
46+
"version": 1,
47+
"kibanaSavedObjectMeta": {
48+
"searchSourceJSON": "{\"index\":\"jmeter_metrics\",\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}"
49+
}
50+
},
51+
"_meta": {
52+
"savedObjectVersion": 1
53+
}
54+
},
55+
{
56+
"_id": "Controls_visualization",
57+
"_type": "visualization",
58+
"_source": {
59+
"title": "Controls",
60+
"visState": "{\"title\":\"Controls\",\"type\":\"input_control_vis\",\"params\":{\"controls\":[{\"fieldName\":\"es-testName.keyword\",\"id\":\"1542568300307\",\"indexPattern\":\"jmeter_metrics\",\"label\":\"Profile\",\"options\":{\"multiselect\":true,\"order\":\"desc\",\"size\":5,\"type\":\"terms\"},\"type\":\"list\"},{\"id\":\"1542568419863\",\"indexPattern\":\"jmeter_metrics\",\"fieldName\":\"es-runid.keyword\",\"label\":\"RunId\",\"type\":\"list\",\"options\":{\"type\":\"terms\",\"multiselect\":true,\"size\":5,\"order\":\"desc\"}}],\"updateFiltersOnChange\":true,\"useTimeFilter\":true},\"aggs\":[]}",
61+
"uiStateJSON": "{}",
62+
"description": "",
63+
"version": 1,
64+
"kibanaSavedObjectMeta": {
65+
"searchSourceJSON": "{}"
66+
}
67+
},
68+
"_meta": {
69+
"savedObjectVersion": 1
70+
}
71+
},
72+
{
73+
"_id": "Aggregate_report_visualization",
74+
"_type": "visualization",
75+
"_source": {
76+
"title": "Aggregate report",
77+
"visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{\"customLabel\":\"Total\"},\"schema\":\"metric\",\"type\":\"count\"},{\"enabled\":true,\"id\":\"4\",\"params\":{\"customLabel\":\"Records\",\"field\":\"SampleCount\"},\"schema\":\"metric\",\"type\":\"sum\"},{\"enabled\":true,\"id\":\"6\",\"params\":{\"customBucket\":{\"enabled\":true,\"id\":\"6-bucket\",\"params\":{\"customInterval\":\"2h\",\"extended_bounds\":{},\"field\":\"Timestamp\",\"interval\":\"m\",\"min_doc_count\":1},\"schema\":{\"aggFilter\":[],\"deprecate\":false,\"editor\":false,\"group\":\"none\",\"max\":null,\"min\":0,\"name\":\"bucketAgg\",\"params\":[],\"title\":\"Bucket Agg\"},\"type\":\"date_histogram\"},\"customLabel\":\"per sec.\",\"customMetric\":{\"enabled\":true,\"id\":\"6-metric\",\"params\":{\"field\":\"SampleCount\",\"json\":\"{ \\\"script\\\" : \\\"_value/60\\\" }\"},\"schema\":{\"aggFilter\":[\"!top_hits\",\"!percentiles\",\"!percentile_ranks\",\"!median\",\"!std_dev\",\"!sum_bucket\",\"!avg_bucket\",\"!min_bucket\",\"!max_bucket\",\"!derivative\",\"!moving_avg\",\"!serial_diff\",\"!cumulative_sum\"],\"deprecate\":false,\"editor\":false,\"group\":\"none\",\"max\":null,\"min\":0,\"name\":\"metricAgg\",\"params\":[],\"title\":\"Metric Agg\"},\"type\":\"sum\"}},\"schema\":\"metric\",\"type\":\"avg_bucket\"},{\"enabled\":true,\"id\":\"3\",\"params\":{\"customLabel\":\"AVG resp.\",\"field\":\"ResponseTime\",\"json\":\"{ \\\"script\\\" : \\\"_value/1000\\\" }\"},\"schema\":\"metric\",\"type\":\"avg\"},{\"enabled\":true,\"id\":\"7\",\"params\":{\"customLabel\":\".\",\"field\":\"ResponseTime\",\"json\":\"{ \\\"script\\\" : \\\"_value/1000\\\" }\",\"percents\":[97]},\"schema\":\"metric\",\"type\":\"percentiles\"},{\"enabled\":true,\"id\":\"5\",\"params\":{\"customLabel\":\"Errors\",\"field\":\"ErrorCount\"},\"schema\":\"metric\",\"type\":\"sum\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"customLabel\":\"Transaction\",\"field\":\"SampleLabel.keyword\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"size\":5},\"schema\":\"bucket\",\"type\":\"terms\"}],\"params\":{\"perPage\":null,\"showMeticsAtAllLevels\":false,\"showMetricsAtAllLevels\":false,\"showPartialRows\":false,\"showTotal\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"totalFunc\":\"count\"},\"title\":\"Aggregate report\",\"type\":\"table\"}",
78+
"uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}",
79+
"description": "",
80+
"version": 1,
81+
"kibanaSavedObjectMeta": {
82+
"searchSourceJSON": "{\"index\":\"jmeter_metrics\",\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[]}"
83+
}
84+
},
85+
"_meta": {
86+
"savedObjectVersion": 1
87+
}
88+
}
89+
]

docs/logstash.conf

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
input {
22
kafka {
33
bootstrap_servers => "localhost:9092"
4-
topics => [ "test" ]
4+
topics => [ "JMETER_METRICS" ]
55
codec => "json"
6-
group_id => "GRP_TEST_LOGSTASH_P_1"
6+
group_id => "GRP_JMETER_METRICS_LOGSTASH_01"
77
auto_offset_reset => "earliest"
88
}
99
}
@@ -12,15 +12,52 @@ filter {
1212
json {
1313
source => "message"
1414
}
15+
16+
# Logstash has strange implementation for json filter above.
17+
# If it sees a field named @timestamp, then it expects it to be a seconds based value (UNIX rather than UNIX_MS) and tries to parse on its own to reuse as event's @timestamp.
18+
# In our case, @timestamp is milli-seconds based long, hence it fails to parse and causes a warning with _timestampparsefailure tag.
19+
20+
if "_timestampparsefailure" in [tags] {
21+
date {
22+
match => [ "_@timestamp", "UNIX_MS" ]
23+
remove_tag => "_timestampparsefailure"
24+
remove_field => "_@timestamp"
25+
}
26+
}
27+
28+
date{
29+
match => [ "ElapsedTime", "yyyy-MM-dd HH:mm:ss" ]
30+
target => ElapsedTime
31+
}
32+
33+
date{
34+
match => [ "Timestamp", "ISO8601" ]
35+
target => Timestamp
36+
}
37+
38+
date{
39+
match => [ "SampleStartTime", "ISO8601" ]
40+
target => SampleStartTime
41+
}
42+
43+
date{
44+
match => [ "SampleEndTime", "ISO8601" ]
45+
target => SampleEndTime
46+
}
47+
48+
ruby {
49+
code => "if (event.get('tags') != nil) && event.get('tags').length == 0 then event.remove('tags') end"
50+
}
1551
}
1652

1753
output {
1854
#stdout { codec => rubydebug }
1955

2056
elasticsearch {
21-
index => "jmeter_metrics-%{+xxxx-ww}" # Weekly index
57+
index => "jmeter_metrics-%{+yyyy-MM-dd}"
2258
hosts => ["localhost:9201"]
2359
user => "elastic"
2460
password => "changeme"
61+
document_type => "logs"
2562
}
2663
}

src/main/java/io/github/rahulsinghai/jmeter/backendlistener/kafka/JSONMetric.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -288,19 +288,19 @@ public Date getElapsedTime(boolean forBuildComparison) {
288288
if (forBuildComparison) {
289289
sElapsed =
290290
String.format(
291-
"2017-01-01 %02d:%02d:%02d",
291+
"2019-07-01 %02d:%02d:%02d",
292292
cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
293293
} else {
294294
sElapsed =
295295
String.format(
296296
"%s %02d:%02d:%02d",
297-
DateTimeFormatter.ofPattern("yyyy-mm-dd").format(LocalDateTime.now()),
297+
DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()),
298298
cal.get(Calendar.HOUR_OF_DAY),
299299
cal.get(Calendar.MINUTE),
300300
cal.get(Calendar.SECOND));
301301
}
302302

303-
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
303+
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
304304
try {
305305
return formatter.parse(sElapsed);
306306
} catch (ParseException e) {

0 commit comments

Comments
 (0)