UNPKG

@lokalise/fastify-extras

Version:

Opinionated set of fastify plugins, commonly used in Lokalise

76 lines 2.86 kB
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