From 8719cc6265f68ddd4633207ea34e91b1b11a4664 Mon Sep 17 00:00:00 2001 From: fenos Date: Fri, 20 Feb 2026 12:00:24 +0100 Subject: [PATCH] feat: delta metrics --- src/app.ts | 9 +++++++++ src/config.ts | 2 ++ src/internal/monitoring/otel-metrics.ts | 10 ++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/app.ts b/src/app.ts index b6263ea8..be0a0e5f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -59,6 +59,15 @@ const build = (opts: buildOpts = {}): FastifyInstance => { app.addSchema(schemas.authSchema) app.addSchema(schemas.errorSchema) + // Fixes security vulnerability: + // https://hackerone.com/reports/3464114 + app.addHook('onRequest', async (request, reply) => { + const contentType = request.headers['content-type'] + if (contentType && contentType.includes('\t')) { + return reply.code(400).send({ error: 'Invalid Content-Type header' }) + } + }) + app.register(plugins.signals) app.register(plugins.tenantId) app.register( diff --git a/src/config.ts b/src/config.ts index bd8356c9..2eca990a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -180,6 +180,7 @@ type StorageConfigType = { prometheusMetricsEnabled: boolean prometheusMetricsIncludeTenantId: boolean otelMetricsEnabled: boolean + otelMetricsTemporality: 'DELTA' | 'CUMULATIVE' otelMetricsExportIntervalMs: number cdnPurgeEndpointURL?: string cdnPurgeEndpointKey?: string @@ -443,6 +444,7 @@ export function getConfig(options?: { reload?: boolean }): StorageConfigType { prometheusMetricsIncludeTenantId: getOptionalConfigFromEnv('PROMETHEUS_METRICS_INCLUDE_TENANT') === 'true', otelMetricsEnabled: getOptionalConfigFromEnv('OTEL_METRICS_ENABLED') === 'true', + otelMetricsTemporality: getOptionalConfigFromEnv('OTEL_METRICS_TEMPORALITY') || 'CUMULATIVE', otelMetricsExportIntervalMs: parseInt( getOptionalConfigFromEnv('OTEL_METRICS_EXPORT_INTERVAL_MS') || '60000', 10 diff --git a/src/internal/monitoring/otel-metrics.ts b/src/internal/monitoring/otel-metrics.ts index d423ff59..553eef32 100644 --- a/src/internal/monitoring/otel-metrics.ts +++ b/src/internal/monitoring/otel-metrics.ts @@ -6,9 +6,10 @@ import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc' import { PrometheusExporter } from '@opentelemetry/exporter-prometheus' import { CompressionAlgorithm } from '@opentelemetry/otlp-exporter-base' import { + AggregationTemporality, + AggregationType, MeterProvider, PeriodicExportingMetricReader, - AggregationType, } from '@opentelemetry/sdk-metrics' import { HostMetrics } from '@opentelemetry/host-metrics' import { registerInstrumentations } from '@opentelemetry/instrumentation' @@ -19,7 +20,8 @@ import * as os from 'os' import { logger, logSchema } from '@internal/monitoring/logger' import { FastifyReply, FastifyRequest } from 'fastify' -const { version, otelMetricsExportIntervalMs, otelMetricsEnabled, region } = getConfig() +const { version, otelMetricsExportIntervalMs, otelMetricsEnabled, otelMetricsTemporality, region } = + getConfig() let prometheusExporter: PrometheusExporter | undefined @@ -85,6 +87,10 @@ if (otelMetricsEnabled) { compression: process.env.OTEL_EXPORTER_OTLP_COMPRESSION as CompressionAlgorithm, headers: exporterHeaders, metadata: grpcMetadata, + temporalityPreference: + otelMetricsTemporality === 'DELTA' + ? AggregationTemporality.DELTA + : AggregationTemporality.CUMULATIVE, }) readers.push(