import { IMetricListener } from "./IMetricListener" ; import { IMetricContext } from "./contexts" ; import { LogService } from ".." ; category export class Metrics { private listeners : IMetricListener [ ] = [ ] ; private requestStartTimes : { [ contextId ] : number ; } = { } ; private uid = 0 ; param { Metrics } parent constructor ( parent = null ) { if ( parent !== null ) { this . registerListener ( { onIncrement ( metricName , context , amount ) { parent . listeners . forEach ( h => h . onIncrement ( metricName , context , amount ) ) ; } , onDecrement ( metricName , context , amount ) { parent . listeners . forEach ( h => h . onDecrement ( metricName , context , amount ) ) ; } , onReset ( metricName , context ) { parent . listeners . forEach ( h => h . onReset ( metricName , context ) ) ; } , onStartMetric ( metricName , context ) { parent . listeners . forEach ( h => h . onStartMetric ( metricName , context ) ) ; } , onEndMetric ( metricName , context , timeMs ) { parent . listeners . forEach ( h => h . onEndMetric ( metricName , context , timeMs ) ) ; } , } ) ; } } param { IMetricListener } listener public registerListener ( listener ) { this . listeners . push ( listener ) ; } param { IMetricListener } listener public unregisterListener ( listener ) { const idx = this . listeners . indexOf ( listener ) ; if ( idx !== - 1 ) this . listeners . splice ( idx , 1 ) ; } param { string } metricName param { IMetricContext } context public start ( metricName , context ) { this . requestStartTimes [ context . uniqueId ] = new Date ( ) . getTime ( ) ; this . listeners . forEach ( h => h . onStartMetric ( metricName , context ) ) ; } param { string } metricName param { IMetricContext } context public end ( metricName , context ) { const timeMs = ( new Date ( ) . getTime ( ) ) - this . requestStartTimes [ context . uniqueId ] ; delete this . requestStartTimes [ context . uniqueId ] ; this . listeners . forEach ( h => h . onEndMetric ( metricName , context , timeMs ) ) ; const trimmedContext = { } ; for ( const key of Object . keys ( context ) ) { if ( key === 'client' ) { const client = context [ key ] ; trimmedContext [ key ] = `<MatrixClient ${ client [ 'userId' ] || 'NoCachedUserID' }>` ; } else if ( key === 'intent' ) { const intent = context [ key ] ; trimmedContext [ key ] = `<Intent ${ intent [ 'userId' ] || 'NoImpersonatedUserID' }>` ; } else { trimmedContext [ key ] = context [ key ] ; } } LogService . trace ( "Metrics" , metricName , trimmedContext , timeMs ) ; } param { string } metricName param { IMetricContext } context param { number } amount public increment ( metricName , context , amount ) { this . listeners . forEach ( h => h . onIncrement ( metricName , context , amount ) ) ; } param { string } metricName param { IMetricContext } context param { number } amount public decrement ( metricName , context , amount ) { this . listeners . forEach ( h => h . onDecrement ( metricName , context , amount ) ) ; } param { string } metricName param { IMetricContext } context public reset ( metricName , context ) { this . listeners . forEach ( h => h . onReset ( metricName , context ) ) ; } param { IMetricContext } context returns { IMetricContext } public assignUniqueContextId ( context ) { context . uniqueId = `${ new Date ( ) . getTime ( ) }-${ this . uid ++ }` ; return context ; } }