Skip to content

Commit

Permalink
feat: add kill switch for client metrics (#4829)
Browse files Browse the repository at this point in the history
This PR adds a killswitch for client metrics that we can use to disable
metrics in our cloud offering.
  • Loading branch information
FredrikOseberg committed Sep 26, 2023
1 parent d16334f commit b919c44
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/lib/__snapshots__/create-config.test.ts.snap
Expand Up @@ -79,6 +79,7 @@ exports[`should create default config 1`] = `
"demo": false,
"dependentFeatures": false,
"disableBulkToggle": false,
"disableMetrics": false,
"disableNotifications": false,
"doraMetrics": false,
"embedProxy": true,
Expand Down Expand Up @@ -117,6 +118,7 @@ exports[`should create default config 1`] = `
"demo": false,
"dependentFeatures": false,
"disableBulkToggle": false,
"disableMetrics": false,
"disableNotifications": false,
"doraMetrics": false,
"embedProxy": true,
Expand Down
29 changes: 29 additions & 0 deletions src/lib/routes/client-api/metrics.test.ts
Expand Up @@ -254,3 +254,32 @@ test('should return a 200 if required fields are there', async () => {
})
.expect(202);
});

test('should return 204 if metrics are disabled by feature flag', async () => {
const { request: localRequest } = await getSetup({
experimental: {
flags: {
disableMetrics: true,
},
},
});

await localRequest
.post('/api/client/metrics')
.send({
appName: 'demo',
someParam: 'some-value',
somOtherParam: 'some--other-value',
bucket: {
start: Date.now(),
stop: Date.now(),
toggles: {
toggleLastSeen: {
yes: 200,
no: 0,
},
},
},
})
.expect(204);
});
30 changes: 19 additions & 11 deletions src/lib/routes/client-api/metrics.ts
Expand Up @@ -58,25 +58,33 @@ export default class ClientMetricsController extends Controller {
responses: {
...getStandardResponses(400),
202: emptyResponse,
204: emptyResponse,
},
}),
],
});
}

async registerMetrics(req: IAuthRequest, res: Response): Promise<void> {
try {
const { body: data, ip: clientIp, user } = req;
data.environment = this.metricsV2.resolveMetricsEnvironment(
user,
data,
);
await this.clientInstanceService.registerInstance(data, clientIp);
if (this.config.flagResolver.isEnabled('disableMetrics')) {
res.status(204).end();
} else {
try {
const { body: data, ip: clientIp, user } = req;
data.environment = this.metricsV2.resolveMetricsEnvironment(
user,
data,
);
await this.clientInstanceService.registerInstance(
data,
clientIp,
);

await this.metricsV2.registerClientMetrics(data, clientIp);
res.status(202).end();
} catch (e) {
res.status(400).end();
await this.metricsV2.registerClientMetrics(data, clientIp);
res.status(202).end();
} catch (e) {
res.status(400).end();
}
}
}
}
7 changes: 7 additions & 0 deletions src/lib/routes/proxy-api/index.ts
Expand Up @@ -108,6 +108,7 @@ export default class ProxyController extends Controller {
requestBody: createRequestSchema('clientMetricsSchema'),
responses: {
200: emptyResponse,
204: emptyResponse,
...getStandardResponses(400, 401, 404),
},
}),
Expand Down Expand Up @@ -189,6 +190,12 @@ export default class ProxyController extends Controller {
if (!this.config.flagResolver.isEnabled('embedProxy')) {
throw new NotFoundError();
}

if (this.config.flagResolver.isEnabled('disableMetrics')) {
res.sendStatus(204);
return;
}

await this.services.proxyService.registerProxyMetrics(
req.user,
req.body,
Expand Down
7 changes: 6 additions & 1 deletion src/lib/types/experimental.ts
Expand Up @@ -30,7 +30,8 @@ export type IFlagKey =
| 'accessOverview'
| 'privateProjects'
| 'dependentFeatures'
| 'datadogJsonTemplate';
| 'datadogJsonTemplate'
| 'disableMetrics';

export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;

Expand Down Expand Up @@ -142,6 +143,10 @@ const flags: IFlags = {
process.env.UNLEASH_EXPERIMENTAL_DATADOG_JSON_TEMPLATE,
false,
),
disableMetrics: parseEnvVarBoolean(
process.env.UNLEASH_EXPERIMENTAL_DISABLE_METRICS,
false,
),
};

export const defaultExperimentalOptions: IExperimentalOptions = {
Expand Down
39 changes: 39 additions & 0 deletions src/test/e2e/api/proxy/proxy.e2e.test.ts
Expand Up @@ -1193,3 +1193,42 @@ test('should NOT evaluate disabled strategies when returning toggles', async ()
});
});
});

test('should return 204 if metrics are disabled', async () => {
const localApp = await setupAppWithAuth(db.stores, {
frontendApiOrigins: ['https://example.com'],
experimental: {
flags: {
disableMetrics: true,
},
},
});

const frontendToken =
await localApp.services.apiTokenService.createApiTokenWithProjects({
type: ApiTokenType.FRONTEND,
projects: ['*'],
environment: 'default',
tokenName: `disabledMetric-token-${randomId()}`,
});

const appName = randomId();
const instanceId = randomId();
const featureName = 'metricsDisabled';

const now = new Date();

await localApp.request
.post('/api/frontend/client/metrics')
.set('Authorization', frontendToken.secret)
.send({
appName,
instanceId,
bucket: {
start: now,
stop: now,
toggles: { [featureName]: { yes: 2, no: 20 } },
},
})
.expect(204);
});

0 comments on commit b919c44

Please sign in to comment.