-
Notifications
You must be signed in to change notification settings - Fork 52
/
nodeHttpRequestMetrics.js
102 lines (89 loc) · 4.01 KB
/
nodeHttpRequestMetrics.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
const { Stopwatch } = require('measured-core');
/**
* The default reporting interval for requests
* @type {number}
*/
const DEFAULT_REQUEST_METRICS_REPORTING_INTERVAL_IN_SECONDS = 10;
/**
* This module has functions needed to create middlewares for frameworks such as express and koa.
* It also exports the 2 functions needed to implement your own middleware.
* If you implement a middleware for a framework not implemented here, please contribute it back.
*
* @module node-http-request-metrics
*/
module.exports = {
/**
* Creates an Express middleware that reports a timer on request data.
* With this middleware you will get requests counts and latency percentiles all filterable by status codes, http method, and uri paths.
*
* @param {SelfReportingMetricsRegistry} metricsRegistry
* @param {number} [reportingIntervalInSeconds]
* @return {Function}
*/
createExpressMiddleware: (metricsRegistry, reportingIntervalInSeconds) => {
return (req, res, next) => {
const stopwatch = module.exports.onRequestStart();
res.on('finish', () => {
const { method } = req;
const { statusCode } = res;
const uri = req.route ? req.route.path : '_unknown';
module.exports.onRequestEnd(metricsRegistry, stopwatch, method, statusCode, uri, reportingIntervalInSeconds);
});
next();
};
},
/**
* Creates a Koa middleware that reports a timer on request data.
* With this middleware you will get requests counts and latency percentiles all filterable by status codes, http method, and uri paths.
*
* @param {SelfReportingMetricsRegistry} metricsRegistry
* @param {number} [reportingIntervalInSeconds]
* @return {Function}
*/
createKoaMiddleware: (metricsRegistry, reportingIntervalInSeconds) => async (ctx, next) => {
const stopwatch = module.exports.onRequestStart();
const { req, res } = ctx;
res.once('finish', () => {
const { method } = req;
const { statusCode } = res;
const uri = ctx._matchedRoute || '_unknown';
module.exports.onRequestEnd(metricsRegistry, stopwatch, method, statusCode, uri, reportingIntervalInSeconds);
});
await next();
},
/**
* At the start of the request, create a stopwatch, that starts tracking how long the request is taking.
* @return {Stopwatch}
*/
onRequestStart: () => {
return new Stopwatch();
},
/**
* When the request ends stop the stop watch and create or update the timer for requests that tracked by method, status code, path.
* The timers (meters and histograms) that get reported will be filterable by status codes, http method, the uri path.
* You will be able to create dash boards such as success percentage, latency percentiles by uri path and method, etc.
*
* @param {SelfReportingMetricsRegistry} metricsRegistry The Self Reporting Metrics Registry
* @param {Stopwatch} stopwatch The stopwatch created by onRequestStart
* @param {string} method The Http Method for the request
* @param {string|number} statusCode The status code for the response
* @param {string} [uri] The uri path for the request. Please note to avoid out of control time series dimension creation spread,
* you would want to strip out ids and or other variables from the uri path.
* @param {number} [reportingIntervalInSeconds] override the reporting interval defaults to every 10 seconds.
*/
onRequestEnd: (metricsRegistry, stopwatch, method, statusCode, uri, reportingIntervalInSeconds) => {
reportingIntervalInSeconds = reportingIntervalInSeconds || DEFAULT_REQUEST_METRICS_REPORTING_INTERVAL_IN_SECONDS;
const customDimensions = {
statusCode: `${statusCode}`,
method: `${method}`
};
if (uri) {
customDimensions.uri = uri;
}
// get or create the timer for the request count/latency timer
const requestTimer = metricsRegistry.getOrCreateTimer('requests', customDimensions, reportingIntervalInSeconds);
// stop the request latency counter
const time = stopwatch.end();
requestTimer.update(time);
}
};