diff --git a/src/lib/metrics.test.ts b/src/lib/metrics.test.ts index d72b6cc61f..3e796c89fc 100644 --- a/src/lib/metrics.test.ts +++ b/src/lib/metrics.test.ts @@ -130,7 +130,7 @@ test('should collect metrics for requests', async () => { const metrics = await prometheusRegister.metrics(); expect(metrics).toMatch( - /http_request_duration_milliseconds\{quantile="0\.99",path="somePath",method="GET",status="200",appName="undefined"\}.*1337/, + /http_request_duration_milliseconds\{quantile="0\.99",path="somePath",method="GET",status="200",appName="undefined",connectionId="undefined"\}.*1337/, ); }); diff --git a/src/lib/metrics.ts b/src/lib/metrics.ts index 02b1373336..863417a291 100644 --- a/src/lib/metrics.ts +++ b/src/lib/metrics.ts @@ -124,7 +124,7 @@ export function registerPrometheusMetrics( const requestDuration = createSummary({ name: 'http_request_duration_milliseconds', help: 'App response time', - labelNames: ['path', 'method', 'status', 'appName'], + labelNames: ['path', 'method', 'status', 'appName', 'connectionId'], percentiles: [0.1, 0.5, 0.9, 0.95, 0.99], maxAgeSeconds: 600, ageBuckets: 5, @@ -700,13 +700,14 @@ export function registerPrometheusMetrics( eventBus.on( events.REQUEST_TIME, - ({ path, method, time, statusCode, appName }) => { + ({ path, method, time, statusCode, appName, connectionId }) => { requestDuration .labels({ path, method, status: statusCode, appName, + connectionId, }) .observe(time); }, diff --git a/src/lib/middleware/response-time-metrics.ts b/src/lib/middleware/response-time-metrics.ts index 92d5e46614..4a1928bfc6 100644 --- a/src/lib/middleware/response-time-metrics.ts +++ b/src/lib/middleware/response-time-metrics.ts @@ -55,12 +55,19 @@ export function responseTimeMetrics( // when pathname is undefined use a fallback pathname = pathname ?? collapse(req.path); let appName: string | undefined; + let connectionId: string | undefined; if ( !flagResolver.isEnabled('responseTimeWithAppNameKillSwitch') && (instanceStatsService.getAppCountSnapshot('7d') ?? appNameReportingThreshold) < appNameReportingThreshold ) { - appName = req.headers['unleash-appname'] ?? req.query.appName; + appName = + req.headers['x-unleash-appname'] ?? + req.headers['unleash-appname'] ?? + req.query.appName; + if (flagResolver.isEnabled('uniqueSdkTracking')) { + connectionId = req.headers['x-unleash-connection-id']; + } } const timingInfo = { @@ -69,6 +76,7 @@ export function responseTimeMetrics( statusCode, time, appName, + connectionId, }; if (!res.locals.responseTimeEmitted) { res.locals.responseTimeEmitted = true; diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index 5e0f22052a..34d9a62bd9 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -61,7 +61,8 @@ export type IFlagKey = | 'etagVariant' | 'oidcRedirect' | 'deltaApi' - | 'newHostedAuthHandler'; + | 'newHostedAuthHandler' + | 'uniqueSdkTracking'; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; @@ -290,6 +291,10 @@ const flags: IFlags = { process.env.UNLEASH_EXPERIMENTAL_NEW_HOSTED_AUTH_HANDLER, false, ), + uniqueSdkTracking: parseEnvVarBoolean( + process.env.UNLEASH_EXPERIMENTAL_UNIQUE_SDK_TRACKING, + false, + ), }; export const defaultExperimentalOptions: IExperimentalOptions = {