@lokalise/fastify-extras
Version:
Opinionated set of fastify plugins, commonly used in Lokalise
76 lines • 2.86 kB
JavaScript
import { PromisePool } from '@supercharge/promise-pool';
import * as prometheus from 'prom-client';
import { ObservableQueue } from './ObservableQueue.js';
const getMetrics = (prefix, histogramBuckets) => ({
countGauge: new prometheus.Gauge({
name: `${prefix}_jobs_count`,
help: 'Total number of jobs',
labelNames: ['status', 'queue'],
}),
processedDuration: new prometheus.Histogram({
name: `${prefix}_jobs_processed_duration`,
help: 'Processing time of a jobs (processing until finished)',
buckets: histogramBuckets,
labelNames: ['status', 'queue'],
}),
finishedDuration: new prometheus.Histogram({
name: `${prefix}_jobs_finished_duration`,
help: 'Finish time for jobs (created until finished)',
buckets: histogramBuckets,
labelNames: ['status', 'queue'],
}),
});
export class MetricsCollector {
metrics;
options;
registry;
logger;
observedQueues;
constructor(options, registry, logger) {
this.options = options;
this.registry = registry;
this.logger = logger;
this.metrics = this.registerMetrics(this.registry, this.options);
}
/**
* Updates metrics for all discovered queues
*/
async collect() {
if (!this.observedQueues) {
this.observedQueues = (await this.options.queueDiscoverer.discoverQueues())
.filter((queue) => !this.options.excludedQueues.includes(queue.queueName))
.map((queue) => new ObservableQueue(queue.queueName, queue.redisConfig, this.metrics, this.logger));
}
await PromisePool.for(this.observedQueues).process((queue) => {
queue.collect();
});
}
/**
* Stops the metrics collection and cleans up resources
*/
async dispose() {
for (const queue of this.observedQueues ?? []) {
await queue.dispose();
}
}
registerMetrics(registry, { metricsPrefix, histogramBuckets }) {
const metrics = getMetrics(metricsPrefix, histogramBuckets);
const metricNames = Object.keys(metrics);
// If metrics are already registered, just return them to avoid triggering a Prometheus error
if (metricNames.length > 0 && registry.getSingleMetric(metricNames[0] ?? '')) {
const retrievedMetrics = registry.getMetricsAsArray();
const returnValue = {};
for (const metric of retrievedMetrics) {
if (metricNames.includes(metric.name)) {
returnValue[metric.name] = metric;
}
}
return returnValue;
}
for (const metric of Object.values(metrics)) {
registry.registerMetric(metric);
}
return metrics;
}
}
//# sourceMappingURL=MetricsCollector.js.map