mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-31 13:47:02 +02:00
chore: emit CLIENT_METRICS event after sifting (#10376)
https://linear.app/unleash/issue/2-3705/only-emit-client-metrics-after-sifting-metrics Only emits the `CLIENT_METRICS` event after metric sifting. This ensures the event is emitted only for valid metrics tied to known flags, instead of all flags included in the metrics payload. See: https://github.com/Unleash/unleash/pull/10375#discussion_r2218974109
This commit is contained in:
parent
8f0c0ccef3
commit
51f8244a5d
@ -113,7 +113,7 @@ test('process metrics properly even when some names are not url friendly, filter
|
|||||||
);
|
);
|
||||||
|
|
||||||
// only toggle with a bad name gets filtered out
|
// only toggle with a bad name gets filtered out
|
||||||
expect(eventBus.emit).toHaveBeenCalledTimes(1);
|
expect(eventBus.emit).not.toHaveBeenCalled();
|
||||||
expect(lastSeenService.updateLastSeen).not.toHaveBeenCalled();
|
expect(lastSeenService.updateLastSeen).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -251,6 +251,7 @@ export default class ClientMetricsServiceV2 {
|
|||||||
...siftedMetrics,
|
...siftedMetrics,
|
||||||
]);
|
]);
|
||||||
this.lastSeenService.updateLastSeen(siftedMetrics);
|
this.lastSeenService.updateLastSeen(siftedMetrics);
|
||||||
|
this.config.eventBus.emit(CLIENT_METRICS, siftedMetrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerImpactMetrics(impactMetrics: Metric[]) {
|
async registerImpactMetrics(impactMetrics: Metric[]) {
|
||||||
@ -300,7 +301,6 @@ export default class ClientMetricsServiceV2 {
|
|||||||
|
|
||||||
if (clientMetrics.length) {
|
if (clientMetrics.length) {
|
||||||
await this.registerBulkMetrics(clientMetrics);
|
await this.registerBulkMetrics(clientMetrics);
|
||||||
this.config.eventBus.emit(CLIENT_METRICS, clientMetrics);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ import {
|
|||||||
customMetricsSchema,
|
customMetricsSchema,
|
||||||
} from '../shared/schema.js';
|
} from '../shared/schema.js';
|
||||||
import type { IClientMetricsEnv } from '../client-metrics/client-metrics-store-v2-type.js';
|
import type { IClientMetricsEnv } from '../client-metrics/client-metrics-store-v2-type.js';
|
||||||
import { CLIENT_METRICS } from '../../../events/index.js';
|
|
||||||
import type { CustomMetricsSchema } from '../../../openapi/spec/custom-metrics-schema.js';
|
import type { CustomMetricsSchema } from '../../../openapi/spec/custom-metrics-schema.js';
|
||||||
import type { StoredCustomMetric } from '../custom/custom-metrics-store.js';
|
import type { StoredCustomMetric } from '../custom/custom-metrics-store.js';
|
||||||
import type { CustomMetricsService } from '../custom/custom-metrics-service.js';
|
import type { CustomMetricsService } from '../custom/custom-metrics-service.js';
|
||||||
@ -276,7 +275,6 @@ export default class ClientMetricsController extends Controller {
|
|||||||
promises.push(
|
promises.push(
|
||||||
this.metricsV2.registerBulkMetrics(filteredData),
|
this.metricsV2.registerBulkMetrics(filteredData),
|
||||||
);
|
);
|
||||||
this.config.eventBus.emit(CLIENT_METRICS, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -16,9 +16,12 @@ import dbInit, {
|
|||||||
import { startOfHour } from 'date-fns';
|
import { startOfHour } from 'date-fns';
|
||||||
import type TestAgent from 'supertest/lib/agent.d.ts';
|
import type TestAgent from 'supertest/lib/agent.d.ts';
|
||||||
import type { BulkRegistrationSchema } from '../../../openapi/index.js';
|
import type { BulkRegistrationSchema } from '../../../openapi/index.js';
|
||||||
|
import type { EventEmitter } from 'stream';
|
||||||
|
import { CLIENT_METRICS } from '../../../events/index.js';
|
||||||
|
|
||||||
let db: ITestDb;
|
let db: ITestDb;
|
||||||
let config: IUnleashConfig;
|
let config: IUnleashConfig;
|
||||||
|
let eventBus: EventEmitter;
|
||||||
|
|
||||||
async function getSetup(opts?: IUnleashOptions) {
|
async function getSetup(opts?: IUnleashOptions) {
|
||||||
config = createTestConfig(opts);
|
config = createTestConfig(opts);
|
||||||
@ -26,12 +29,16 @@ async function getSetup(opts?: IUnleashOptions) {
|
|||||||
|
|
||||||
const services = createServices(db.stores, config, db.rawDatabase);
|
const services = createServices(db.stores, config, db.rawDatabase);
|
||||||
const app = await getApp(config, db.stores, services);
|
const app = await getApp(config, db.stores, services);
|
||||||
|
|
||||||
|
config.eventBus.emit = vi.fn();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
request: supertest(app),
|
request: supertest(app),
|
||||||
stores: db.stores,
|
stores: db.stores,
|
||||||
services,
|
services,
|
||||||
db: db.rawDatabase,
|
db: db.rawDatabase,
|
||||||
destroy: db.destroy,
|
destroy: db.destroy,
|
||||||
|
eventBus: config.eventBus,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +59,7 @@ beforeAll(async () => {
|
|||||||
stores = setup.stores;
|
stores = setup.stores;
|
||||||
destroy = setup.destroy;
|
destroy = setup.destroy;
|
||||||
services = setup.services;
|
services = setup.services;
|
||||||
|
eventBus = setup.eventBus;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@ -101,13 +109,22 @@ describe('should register unknown flags', () => {
|
|||||||
appName: 'demo',
|
appName: 'demo',
|
||||||
seenAt: expect.any(Date),
|
seenAt: expect.any(Date),
|
||||||
});
|
});
|
||||||
|
expect(eventBus.emit).toHaveBeenCalledWith(
|
||||||
|
CLIENT_METRICS,
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
featureName: 'existing_flag',
|
||||||
|
yes: 200,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('/metrics/bulk endpoint', async () => {
|
test('/metrics/bulk endpoint', async () => {
|
||||||
// @ts-expect-error - cachedFeatureNames is a private property in ClientMetricsServiceV2
|
// @ts-expect-error - cachedFeatureNames is a private property in ClientMetricsServiceV2
|
||||||
services.clientMetricsServiceV2.cachedFeatureNames = vi
|
services.clientMetricsServiceV2.cachedFeatureNames = vi
|
||||||
.fn<() => Promise<string[]>>()
|
.fn<() => Promise<string[]>>()
|
||||||
.mockResolvedValue(['existing_flag']);
|
.mockResolvedValue(['existing_flag_bulk']);
|
||||||
|
|
||||||
const unknownFlag: BulkRegistrationSchema = {
|
const unknownFlag: BulkRegistrationSchema = {
|
||||||
appName: 'demo',
|
appName: 'demo',
|
||||||
@ -123,21 +140,21 @@ describe('should register unknown flags', () => {
|
|||||||
applications: [unknownFlag],
|
applications: [unknownFlag],
|
||||||
metrics: [
|
metrics: [
|
||||||
{
|
{
|
||||||
featureName: 'existing_flag',
|
featureName: 'existing_flag_bulk',
|
||||||
environment: 'development',
|
environment: 'development',
|
||||||
appName: 'demo',
|
appName: 'demo',
|
||||||
timestamp: startOfHour(new Date()),
|
timestamp: startOfHour(new Date()),
|
||||||
yes: 200,
|
yes: 1337,
|
||||||
no: 0,
|
no: 0,
|
||||||
variants: {},
|
variants: {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureName: 'unknown_flag',
|
featureName: 'unknown_flag_bulk',
|
||||||
environment: 'development',
|
environment: 'development',
|
||||||
appName: 'demo',
|
appName: 'demo',
|
||||||
timestamp: startOfHour(new Date()),
|
timestamp: startOfHour(new Date()),
|
||||||
yes: 100,
|
yes: 200,
|
||||||
no: 50,
|
no: 100,
|
||||||
variants: {},
|
variants: {},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -149,10 +166,19 @@ describe('should register unknown flags', () => {
|
|||||||
|
|
||||||
expect(unknownFlags).toHaveLength(1);
|
expect(unknownFlags).toHaveLength(1);
|
||||||
expect(unknownFlags[0]).toMatchObject({
|
expect(unknownFlags[0]).toMatchObject({
|
||||||
name: 'unknown_flag',
|
name: 'unknown_flag_bulk',
|
||||||
environment: 'development',
|
environment: 'development',
|
||||||
appName: 'demo',
|
appName: 'demo',
|
||||||
seenAt: expect.any(Date),
|
seenAt: expect.any(Date),
|
||||||
});
|
});
|
||||||
|
expect(eventBus.emit).toHaveBeenCalledWith(
|
||||||
|
CLIENT_METRICS,
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
featureName: 'existing_flag_bulk',
|
||||||
|
yes: 1337,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user