1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

feat: add kill switch for client metrics (#4829)

This PR adds a killswitch for client metrics that we can use to disable
metrics in our cloud offering.
This commit is contained in:
Fredrik Strand Oseberg 2023-09-26 09:37:42 +02:00 committed by GitHub
parent d16334f3fb
commit b919c445b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 102 additions and 12 deletions

View File

@ -79,6 +79,7 @@ exports[`should create default config 1`] = `
"demo": false,
"dependentFeatures": false,
"disableBulkToggle": false,
"disableMetrics": false,
"disableNotifications": false,
"doraMetrics": false,
"embedProxy": true,
@ -117,6 +118,7 @@ exports[`should create default config 1`] = `
"demo": false,
"dependentFeatures": false,
"disableBulkToggle": false,
"disableMetrics": false,
"disableNotifications": false,
"doraMetrics": false,
"embedProxy": true,

View File

@ -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);
});

View File

@ -58,6 +58,7 @@ export default class ClientMetricsController extends Controller {
responses: {
...getStandardResponses(400),
202: emptyResponse,
204: emptyResponse,
},
}),
],
@ -65,18 +66,25 @@ export default class ClientMetricsController extends Controller {
}
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();
}
}
}
}

View File

@ -108,6 +108,7 @@ export default class ProxyController extends Controller {
requestBody: createRequestSchema('clientMetricsSchema'),
responses: {
200: emptyResponse,
204: emptyResponse,
...getStandardResponses(400, 401, 404),
},
}),
@ -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,

View File

@ -30,7 +30,8 @@ export type IFlagKey =
| 'accessOverview'
| 'privateProjects'
| 'dependentFeatures'
| 'datadogJsonTemplate';
| 'datadogJsonTemplate'
| 'disableMetrics';
export type IFlags = Partial<{ [key in IFlagKey]: boolean | Variant }>;
@ -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 = {

View File

@ -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);
});