1
1
const client = require ( 'prom-client' ) ;
2
2
const Boom = require ( 'boom' ) ;
3
3
4
- const requestCounter = new client . Counter ( {
5
- name : 'http_requests_total' ,
6
- help : 'HTTP Requests per seconds' ,
7
- labelNames : [ 'method' , 'path' ] ,
8
- } ) ;
9
- const { collectDefaultMetrics } = client ;
10
- collectDefaultMetrics ( 5000 ) ;
4
+ const metrics = {
5
+ // This allows to measure request response time repartition by quantiles
6
+ httpRequestDurationMilliseconds : new client . Summary ( {
7
+ name : 'http_request_duration_milliseconds' ,
8
+ help : 'Response time in milliseconds by quantiles.' ,
9
+ labelNames : [ 'method' , 'path' , 'status' ] ,
10
+ } ) ,
11
+ // This allows to rank request response time in 3 buckets: 0-500, 500-1500 and 1500-+Inf (used for Apdex)
12
+ httpRequestBucketMilliseconds : new client . Histogram ( {
13
+ name : 'http_request_bucket_milliseconds' ,
14
+ help : 'Bucketed response time in milliseconds.' ,
15
+ buckets : [ 500 , 1500 ] ,
16
+ labelNames : [ 'method' , 'path' , 'status' ] ,
17
+ } ) ,
18
+ // Total request counter to measure usage of each routes
19
+ httpRequestsTotal : new client . Counter ( {
20
+ name : 'http_requests_total' ,
21
+ help : 'Paths taken in the app.' ,
22
+ labelNames : [ 'path' , 'method' ] ,
23
+ } ) ,
24
+ // Total server error counter (crashes and timeouts)
25
+ httpRequestsErrorTotal : new client . Counter ( {
26
+ name : 'http_server_error_total' ,
27
+ help : 'Error codes returned.' ,
28
+ labelNames : [ 'path' , 'method' ] ,
29
+ } ) ,
30
+ // Total and Type of error counter
31
+ httpRequestsErrorTotalByType : new client . Counter ( {
32
+ name : 'http_error_by_type' ,
33
+ help : 'Number of errors by error code' ,
34
+ labelNames : [ 'path' , 'method' , 'code' ] ,
35
+ } ) ,
36
+ } ;
11
37
12
38
exports . register = ( server , config , next ) => {
39
+ client . collectDefaultMetrics ( 5000 ) ;
13
40
const { User } = server . plugins . users . models ;
14
41
15
42
server . auth . strategy ( 'metrics' , 'basic' , {
@@ -26,17 +53,30 @@ exports.register = (server, config, next) => {
26
53
27
54
server . route ( {
28
55
method : 'GET' ,
29
- path : '/metrics' ,
56
+ path : config . metricsPath ,
30
57
config : { auth : 'metrics' } ,
31
58
handler ( req , res ) {
32
59
res ( client . register . metrics ( ) )
33
60
. type ( client . register . contentType ) ;
34
61
} ,
35
62
} ) ;
36
63
37
- server . on ( { name : 'request-internal' , filter : 'handler' } , ( req ) => {
38
- if ( ! / \/ ( a s s e t s | f a v i c o n | m e t r i c s ) / . test ( req . path ) ) {
39
- requestCounter . labels ( req . method , req . route . path ) . inc ( ) ;
64
+ server . on ( { name : 'request-internal' , filter : 'received' } , ( req ) => {
65
+ if ( req . path !== config . metricsPath && req . path . startsWith ( '/api' ) ) {
66
+ metrics . httpRequestsTotal . inc ( { path : req . path , method : req . method } ) ;
67
+ }
68
+ } ) ;
69
+
70
+ server . on ( 'response' , ( req ) => {
71
+ if ( req . path !== config . metricsPath && req . path . startsWith ( '/api' ) ) {
72
+ const time = req . info . responded - req . info . received ;
73
+ metrics . httpRequestDurationMilliseconds . labels ( req . method , req . path , req . response . statusCode ) . observe ( time ) ;
74
+ metrics . httpRequestBucketMilliseconds . labels ( req . method , req . path , req . response . statusCode ) . observe ( time ) ;
75
+
76
+ if ( req . response . statusCode >= 400 ) {
77
+ metrics . httpRequestsErrorTotal . inc ( { path : req . path , method : req . method } ) ;
78
+ metrics . httpRequestsErrorTotalByType . inc ( { path : req . path , method : req . method , code : req . response . statusCode } ) ;
79
+ }
40
80
}
41
81
} ) ;
42
82
0 commit comments