import {PromMetric, PromOptions} from './metric';
import {TimerWrapper, TimerWrapperFactory, Tags, Providers} from '@btilford/ts-base-core';
import {Histogram as Delegate, Registry} from 'prom-client';
export class PromTimerWrapper<T> extends PromMetric implements TimerWrapper<T> {
protected readonly impl: Delegate<any>;
constructor(name: string, tags: Tags, options: PromOptions) {
super(name, tags, options);
this.impl = new Delegate({
name:this.name,
help: options.help,
registers: options.registry || [Providers.provide(Registry)],
aggregator: options.aggregator,
labelNames: [...this.supportedLabels],
});
}
wrap(func: (...args: unknown[]) => T): (...args: unknown[]) => T {
const timer = this.impl;
const _tags = this.filterTags(this.tags);
return function prometheusTimerWrapper(...args: unknown[]): T {
const end = timer.startTimer(_tags);
const result: T = func(...args);
try {
if (result instanceof Promise) {
result.then(result => {
end();
return result;
}).catch(err => {
end();
return err;
});
} else {
end();
}
} catch (error) {
end();
throw error;
}
return result;
};
}
}
export class PromTimerWrapperFactory extends TimerWrapperFactory {
protected readonly options: PromOptions;
constructor(options: PromOptions) {
super();
this.options = { ...options };
}
timer<T>(name: string, tags): TimerWrapper<T> {
return new PromTimerWrapper(name, tags, this.options);
}
asyncTimer<T>(name: string, tags?): TimerWrapper<Promise<T>> {
return new PromTimerWrapper(name, tags, this.options);
}
}
|