import Debug from "debug" ; import promClient from "prom-client" ; const debug = Debug ( "yildiz:http:metrics" ) ; const promDefaultMetrics = promClient . collectDefaultMetrics ; const promRegistry = promClient . Registry ; const FACTORY_METRICS_PREFIX = "__FACTORY__" ; export class Metrics { private prefix : string ; private register : promClient . Registry ; private defaultMetricsIntv ! : number | NodeJS . Timer ; private metrics : { [ key ] : promClient . Counter | promClient . Gauge ; } ; constructor ( prefix ) { this . prefix = prefix === FACTORY_METRICS_PREFIX ? "" : prefix ; this . register = new promRegistry ( ) ; this . metrics = { } ; } public exportType ( ) { return this . register . contentType ; } public exportMetrics ( ) { return this . register . metrics ( ) ; } public getRegister ( ) { return this . register ; } private getCounter ( key ) { if ( this . metrics [ key ] ) { return this . metrics [ key ] ; } this . metrics [ key ] = new promClient . Counter ( { name : `${ key }` , help : `${ key }_help` , registers : [ this . register ] , labelNames : [ "na" , "prefix" ] , } ) ; return this . metrics [ key ] ; } private getGauge ( key ) { key = `gauge_${ key }` ; if ( this . metrics [ key ] ) { return this . metrics [ key ] as promClient . Gauge ; } this . metrics [ key ] = new promClient . Gauge ( { name : `${ key }` , help : `${ key }_help` , registers : [ this . register ] , labelNames : [ "na" , "prefix" ] , } ) ; return this . metrics [ key ] as promClient . Gauge ; } public inc ( key , val = 1 ) { const prefix = this . prefix ; const fullKey = prefix ? `${ prefix }_${ key }` : key ; const counter = this . getCounter ( fullKey ) ; counter . inc ( { prefix } , val , Date . now ( ) ) ; } public set ( key , val ) { if ( val === null || val === undefined ) { throw new Error ( `Please provide value on set ${ key }` ) ; } const prefix = this . prefix ; const fullKey = prefix ? `${ prefix }_${ key }` : key ; const gauge = this . getGauge ( fullKey ) ; gauge . set ( { prefix } , val , Date . now ( ) ) ; } public registerDefault ( ) { this . defaultMetricsIntv = promDefaultMetrics ( { register : this . register , timeout : 5000 , } ) ; debug ( "metrics active." ) ; } public close ( ) { if ( this . defaultMetricsIntv ) { clearInterval ( this . defaultMetricsIntv as NodeJS . Timer ) ; } this . metrics = { } ; this . register . clear ( ) ; } }