11import * as promBundle from 'express-prom-bundle' ;
2+ import * as promClient from 'prom-client' ;
3+ import * as onFinished from 'on-finished' ;
4+ import express = require( 'express' ) ;
5+
26import { MetricsConfig } from '../config' ;
37import { Logger } from '../logger' ;
48
5- export const metricsMiddleware = ( config : MetricsConfig , log : Logger ) => {
6- if ( ! config . enabled ) {
7- return ( req , res , next ) => {
8- next ( ) ;
9- } ;
10- }
11-
9+ export const setupHttpServerMetrics = ( app : express . Express , config : MetricsConfig , log : Logger ) => {
1210 log . info (
1311 'Metrics enabled' ,
1412 'collectDefaultMetrics' ,
@@ -17,13 +15,15 @@ export const metricsMiddleware = (config: MetricsConfig, log: Logger) => {
1715 config . requestDurationBuckets . join ( ',' )
1816 ) ;
1917
18+ const excludeRegExp = / ^ ( (? ! ( r e n d e r ) ) .) * $ / ;
19+
2020 const opts = {
2121 httpDurationMetricName : 'grafana_image_renderer_service_http_request_duration_seconds' ,
2222 metricType : 'histogram' ,
2323 buckets : config . requestDurationBuckets ,
24- excludeRoutes : [ / ^ ( (? ! ( r e n d e r ) ) . ) * $ / ] ,
24+ excludeRoutes : [ excludeRegExp ] ,
2525 promClient : { } ,
26- formatStatusCode : res => {
26+ formatStatusCode : ( res ) => {
2727 if ( res && res . req && res . req . aborted ) {
2828 // Nginx non-standard code 499 Client Closed Request
2929 // Used when the client has closed the request before
@@ -39,6 +39,28 @@ export const metricsMiddleware = (config: MetricsConfig, log: Logger) => {
3939 opts . promClient . collectDefaultMetrics = { } ;
4040 }
4141
42- const bundle = promBundle ( opts ) ;
43- return bundle ;
42+ const metricsMiddleware = promBundle ( opts ) ;
43+ app . use ( metricsMiddleware ) ;
44+
45+ const httpRequestsInFlight = new promClient . Gauge ( {
46+ name : 'grafana_image_renderer_http_request_in_flight' ,
47+ help : 'A gauge of requests currently being served by the image renderer.' ,
48+ } ) ;
49+ app . use ( requestsInFlightMiddleware ( httpRequestsInFlight , excludeRegExp ) ) ;
50+ } ;
51+
52+ const requestsInFlightMiddleware = ( httpRequestsInFlight : promClient . Gauge , excludeRegExp : RegExp ) => {
53+ return ( req , res , next ) => {
54+ const path = req . originalUrl || req . url ;
55+ if ( path . match ( excludeRegExp ) ) {
56+ return next ( ) ;
57+ }
58+
59+ httpRequestsInFlight . inc ( ) ;
60+ onFinished ( res , ( ) => {
61+ httpRequestsInFlight . dec ( ) ;
62+ } ) ;
63+
64+ next ( ) ;
65+ } ;
4466} ;
0 commit comments