This repository has been archived by the owner on May 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
/
index.js
87 lines (70 loc) · 2.89 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const url = require('url');
module.exports = { Plugin: MetricsByEndpoint };
const debug = require('debug')('plugin:metrics-by-endpoint');
let useOnlyRequestNames;
let metricsPrefix;
// NOTE: Will not work with `parallel` - need request UIDs for that
function MetricsByEndpoint(script, events) {
// if(!global.artillery || !global.artillery.log) {
// console.error('artillery-plugin-metrics-endpoint requires Artillery v2');
// return;
// }
// If running in Artillery v2, the plugin should only load in workers
if (global.artillery &&
Number(global.artillery.version.slice(0, 1)) > 1 &&
typeof process.env.LOCAL_WORKER_ID === 'undefined') {
debug('Not running in a worker, exiting');
return;
}
if (!script.config.processor) {
script.config.processor = {};
}
useOnlyRequestNames = script.config.plugins['metrics-by-endpoint'].useOnlyRequestNames || false;
metricsPrefix = script.config.plugins['metrics-by-endpoint'].metricsNamespace || 'plugins.metrics-by-endpoint';
script.config.processor.metricsByEndpoint_afterResponse = metricsByEndpoint_afterResponse;
script.scenarios.forEach(function(scenario) {
scenario.afterResponse = [].concat(scenario.afterResponse || []);
scenario.afterResponse.push('metricsByEndpoint_afterResponse');
});
}
function metricsByEndpoint_afterResponse(req, res, userContext, events, done) {
const targetUrl = userContext.vars.target && url.parse(userContext.vars.target);
const requestUrl = url.parse(req.url);
let baseUrl = '';
if (targetUrl && requestUrl.hostname && targetUrl.hostname !== requestUrl.hostname) {
baseUrl += requestUrl.hostname
}
if (targetUrl && requestUrl.port && targetUrl.port !== requestUrl.port) {
baseUrl += `:${requestUrl.port}`
}
baseUrl += requestUrl.path
let reqName = '';
if (useOnlyRequestNames && req.name) {
reqName += req.name;
} else if (req.name) {
reqName += `${baseUrl} (${req.name})`;
} else {
reqName += baseUrl;
}
const histoName = `${metricsPrefix}.response_time.${reqName}`;
if (res.headers['server-timing']) {
const timing = getServerTimingTotal(res.headers['server-timing']);
events.emit('histogram', `${metricsPrefix}.server-timing.${reqName}`, timing);
}
events.emit('counter', `${metricsPrefix}.${reqName}.codes.${res.statusCode}`, 1);
events.emit('histogram', histoName, res.timings.phases.firstByte);
return done();
}
function getServerTimingTotal(s) {
const matches = s.match(/total;dur=[0-9.]+/ig);
if(matches !== null && matches.length > 0) {
// we always grab the first instance of "total" if there's more than one
return Number(matches[0].split('=')[1] || 0);
} else {
// no match
return -1;
}
}