"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenTelemetryMetrics = void 0;
const api_1 = require("@opentelemetry/api");
const exporter_prometheus_1 = require("@opentelemetry/exporter-prometheus");
const sdk_metrics_1 = require("@opentelemetry/sdk-metrics");
const logger_1 = require("../../helpers/logger");
const config_1 = require("../../initializers/config");
const metric_helpers_1 = require("./metric-helpers");
class OpenTelemetryMetrics {
    constructor() { }
    init(app) {
        if (config_1.CONFIG.OPEN_TELEMETRY.METRICS.ENABLED !== true)
            return;
        app.use((req, res, next) => {
            res.once('finish', () => {
                if (!this.onRequestDuration)
                    return;
                this.onRequestDuration(req, res);
            });
            next();
        });
    }
    registerMetrics() {
        if (config_1.CONFIG.OPEN_TELEMETRY.METRICS.ENABLED !== true)
            return;
        logger_1.logger.info('Registering Open Telemetry metrics');
        const provider = new sdk_metrics_1.MeterProvider({
            views: [
                ...metric_helpers_1.NodeJSObserversBuilder.getViews()
            ]
        });
        provider.addMetricReader(new exporter_prometheus_1.PrometheusExporter({
            host: config_1.CONFIG.OPEN_TELEMETRY.METRICS.PROMETHEUS_EXPORTER.HOSTNAME,
            port: config_1.CONFIG.OPEN_TELEMETRY.METRICS.PROMETHEUS_EXPORTER.PORT
        }));
        api_1.metrics.setGlobalMeterProvider(provider);
        this.meter = api_1.metrics.getMeter('default');
        this.buildRequestObserver();
        this.playbackMetrics = new metric_helpers_1.PlaybackMetrics(this.meter);
        this.playbackMetrics.buildCounters();
        const nodeJSObserversBuilder = new metric_helpers_1.NodeJSObserversBuilder(this.meter);
        nodeJSObserversBuilder.buildObservers();
        const jobQueueObserversBuilder = new metric_helpers_1.JobQueueObserversBuilder(this.meter);
        jobQueueObserversBuilder.buildObservers();
        const statsObserversBuilder = new metric_helpers_1.StatsObserversBuilder(this.meter);
        statsObserversBuilder.buildObservers();
        const livesObserversBuilder = new metric_helpers_1.LivesObserversBuilder(this.meter);
        livesObserversBuilder.buildObservers();
        const viewersObserversBuilder = new metric_helpers_1.ViewersObserversBuilder(this.meter);
        viewersObserversBuilder.buildObservers();
    }
    observePlaybackMetric(video, metrics) {
        this.playbackMetrics.observe(video, metrics);
    }
    buildRequestObserver() {
        const requestDuration = this.meter.createHistogram('http_request_duration_ms', {
            unit: 'milliseconds',
            description: 'Duration of HTTP requests in ms'
        });
        this.onRequestDuration = (req, res) => {
            const duration = Date.now() - res.locals.requestStart;
            requestDuration.record(duration, {
                path: this.buildRequestPath(req.originalUrl),
                method: req.method,
                statusCode: res.statusCode + ''
            });
        };
    }
    buildRequestPath(path) {
        return path.split('?')[0];
    }
    static get Instance() {
        return this.instance || (this.instance = new this());
    }
}
exports.OpenTelemetryMetrics = OpenTelemetryMetrics;
//# sourceMappingURL=metrics.js.map