1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-31 01:16:01 +02:00

feat: Unique connection tracking (#9067)

This commit is contained in:
Mateusz Kwasniewski 2025-01-08 13:36:40 +01:00 committed by GitHub
parent 73515d78ce
commit cef10eee02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 5 deletions

View File

@ -130,7 +130,7 @@ test('should collect metrics for requests', async () => {
const metrics = await prometheusRegister.metrics(); const metrics = await prometheusRegister.metrics();
expect(metrics).toMatch( 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/,
); );
}); });

View File

@ -124,7 +124,7 @@ export function registerPrometheusMetrics(
const requestDuration = createSummary({ const requestDuration = createSummary({
name: 'http_request_duration_milliseconds', name: 'http_request_duration_milliseconds',
help: 'App response time', 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], percentiles: [0.1, 0.5, 0.9, 0.95, 0.99],
maxAgeSeconds: 600, maxAgeSeconds: 600,
ageBuckets: 5, ageBuckets: 5,
@ -700,13 +700,14 @@ export function registerPrometheusMetrics(
eventBus.on( eventBus.on(
events.REQUEST_TIME, events.REQUEST_TIME,
({ path, method, time, statusCode, appName }) => { ({ path, method, time, statusCode, appName, connectionId }) => {
requestDuration requestDuration
.labels({ .labels({
path, path,
method, method,
status: statusCode, status: statusCode,
appName, appName,
connectionId,
}) })
.observe(time); .observe(time);
}, },

View File

@ -55,12 +55,19 @@ export function responseTimeMetrics(
// when pathname is undefined use a fallback // when pathname is undefined use a fallback
pathname = pathname ?? collapse(req.path); pathname = pathname ?? collapse(req.path);
let appName: string | undefined; let appName: string | undefined;
let connectionId: string | undefined;
if ( if (
!flagResolver.isEnabled('responseTimeWithAppNameKillSwitch') && !flagResolver.isEnabled('responseTimeWithAppNameKillSwitch') &&
(instanceStatsService.getAppCountSnapshot('7d') ?? (instanceStatsService.getAppCountSnapshot('7d') ??
appNameReportingThreshold) < appNameReportingThreshold 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 = { const timingInfo = {
@ -69,6 +76,7 @@ export function responseTimeMetrics(
statusCode, statusCode,
time, time,
appName, appName,
connectionId,
}; };
if (!res.locals.responseTimeEmitted) { if (!res.locals.responseTimeEmitted) {
res.locals.responseTimeEmitted = true; res.locals.responseTimeEmitted = true;

View File

@ -61,7 +61,8 @@ export type IFlagKey =
| 'etagVariant' | 'etagVariant'
| 'oidcRedirect' | 'oidcRedirect'
| 'deltaApi' | 'deltaApi'
| 'newHostedAuthHandler'; | 'newHostedAuthHandler'
| 'uniqueSdkTracking';
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>; export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
@ -290,6 +291,10 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_NEW_HOSTED_AUTH_HANDLER, process.env.UNLEASH_EXPERIMENTAL_NEW_HOSTED_AUTH_HANDLER,
false, false,
), ),
uniqueSdkTracking: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_UNIQUE_SDK_TRACKING,
false,
),
}; };
export const defaultExperimentalOptions: IExperimentalOptions = { export const defaultExperimentalOptions: IExperimentalOptions = {