From 4e3872b153a0a1b86df6728d8b92f22405a75866 Mon Sep 17 00:00:00 2001 From: Nicklas Lundin Date: Mon, 2 Dec 2024 11:11:12 +0100 Subject: [PATCH] fix: add platform to the telemetry header --- .../confidence/telemetry/v1/telemetry.proto | 16 +++ packages/sdk/src/Confidence.ts | 1 + packages/sdk/src/FlagResolverClient.test.ts | 13 ++- packages/sdk/src/Telemetry.test.ts | 8 +- packages/sdk/src/Telemetry.ts | 7 +- .../confidence/telemetry/v1/telemetry.ts | 101 ++++++++++++++++++ 6 files changed, 135 insertions(+), 11 deletions(-) diff --git a/packages/sdk/proto/confidence/telemetry/v1/telemetry.proto b/packages/sdk/proto/confidence/telemetry/v1/telemetry.proto index d2bd555..be56821 100644 --- a/packages/sdk/proto/confidence/telemetry/v1/telemetry.proto +++ b/packages/sdk/proto/confidence/telemetry/v1/telemetry.proto @@ -2,8 +2,24 @@ syntax = "proto3"; package confidence.telemetry.v1; +enum Platform { + PLATFORM_UNSPECIFIED = 0; + PLATFORM_JAVA = 1; + PLATFORM_KOTLIN = 2; + PLATFORM_SWIFT = 3; + PLATFORM_JS_WEB = 4; + PLATFORM_JS_SERVER = 5; + PLATFORM_PYTHON = 6; + PLATFORM_GO = 7; + PLATFORM_RUBY = 8; + PLATFORM_RUST = 9; + PLATFORM_FLUTTER_IOS = 10; + PLATFORM_FLUTTER_ANDROID = 11; +} + message Monitoring { repeated LibraryTraces library_traces = 1; + Platform platform = 2; } message LibraryTraces { diff --git a/packages/sdk/src/Confidence.ts b/packages/sdk/src/Confidence.ts index 4c69426..8cb4262 100644 --- a/packages/sdk/src/Confidence.ts +++ b/packages/sdk/src/Confidence.ts @@ -345,6 +345,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { const telemetry = new Telemetry({ disabled: disableTelemetry, logger, + environment, }); let flagResolverClient: FlagResolverClient = new FetchingFlagResolverClient({ clientSecret, diff --git a/packages/sdk/src/FlagResolverClient.test.ts b/packages/sdk/src/FlagResolverClient.test.ts index 4d96d35..2ec457e 100644 --- a/packages/sdk/src/FlagResolverClient.test.ts +++ b/packages/sdk/src/FlagResolverClient.test.ts @@ -12,7 +12,7 @@ import { abortableSleep, FetchBuilder } from './fetch-util'; import { ApplyFlagsRequest, ResolveFlagsRequest } from './generated/confidence/flags/resolver/v1/api'; import { FlagResolution } from './FlagResolution'; import { Telemetry } from './Telemetry'; -import { LibraryTraces_Library, LibraryTraces_TraceId } from './generated/confidence/telemetry/v1/telemetry'; +import { LibraryTraces_Library, LibraryTraces_TraceId, Platform } from './generated/confidence/telemetry/v1/telemetry'; const RESOLVE_ENDPOINT = 'https://resolver.confidence.dev/v1/flags:resolve'; const APPLY_ENDPOINT = 'https://resolver.confidence.dev/v1/flags:apply'; @@ -59,7 +59,7 @@ describe('Client environment Evaluation', () => { }, environment: 'client', resolveTimeout: 10, - telemetry: new Telemetry({ disabled: true, logger: { warn: jest.fn() } }), + telemetry: new Telemetry({ disabled: true, logger: { warn: jest.fn() }, environment: 'client' }), }); describe('apply', () => { @@ -112,7 +112,7 @@ describe('Backend environment Evaluation', () => { }, environment: 'backend', resolveTimeout: 10, - telemetry: new Telemetry({ disabled: true, logger: { warn: jest.fn() } }), + telemetry: new Telemetry({ disabled: true, logger: { warn: jest.fn() }, environment: 'backend' }), }); it('should resolve a full flag object', async () => { @@ -288,7 +288,9 @@ describe('intercept', () => { }); describe('withTelemetryData', () => { - const telemetryMock = jest.mocked(new Telemetry({ disabled: false, logger: { warn: jest.fn() } })); + const telemetryMock = jest.mocked( + new Telemetry({ disabled: false, logger: { warn: jest.fn() }, environment: 'client' }), + ); beforeEach(() => { underTest = withTelemetryData(fetchBuilder, telemetryMock).build(fetchMock); @@ -300,6 +302,7 @@ describe('intercept', () => { traces: [{ id: LibraryTraces_TraceId.TRACE_ID_FLAG_TYPE_MISMATCH }], }, ], + platform: Platform.PLATFORM_JS_WEB, }); }); @@ -309,7 +312,7 @@ describe('intercept', () => { expect(fetchMock).toBeCalledTimes(1); const request = fetchMock.mock.calls[0][0]; expect(request.headers.has('X-Confidence-Telemetry')).toBeTruthy(); - expect(request.headers.get('X-Confidence-Telemetry')).toEqual('CgwIAxIEdGVzdBoCCAM='); + expect(request.headers.get('X-Confidence-Telemetry')).toEqual('CgwIAxIEdGVzdBoCCAMQBA=='); }); }); diff --git a/packages/sdk/src/Telemetry.test.ts b/packages/sdk/src/Telemetry.test.ts index e047eab..693e75b 100644 --- a/packages/sdk/src/Telemetry.test.ts +++ b/packages/sdk/src/Telemetry.test.ts @@ -3,7 +3,7 @@ import { Telemetry } from './Telemetry'; describe('Telemetry', () => { it('registerCounter and increment counter', () => { - const telemetry = new Telemetry({ disabled: false, logger: { warn: jest.fn() } }); + const telemetry = new Telemetry({ disabled: false, logger: { warn: jest.fn() }, environment: 'backend' }); const counter = telemetry.registerCounter({ library: LibraryTraces_Library.LIBRARY_CONFIDENCE, version: '9.9.9', @@ -26,7 +26,7 @@ describe('Telemetry', () => { }); it('registerMeter and add measurement', () => { - const telemetry = new Telemetry({ disabled: false, logger: { warn: jest.fn() } }); + const telemetry = new Telemetry({ disabled: false, logger: { warn: jest.fn() }, environment: 'client' }); const meter = telemetry.registerMeter({ library: LibraryTraces_Library.LIBRARY_CONFIDENCE, version: '9.9.9', @@ -49,7 +49,7 @@ describe('Telemetry', () => { }); it('snapshot is empty when telemetry is disabled', () => { - const telemetry = new Telemetry({ disabled: true, logger: { warn: jest.fn() } }); + const telemetry = new Telemetry({ disabled: true, logger: { warn: jest.fn() }, environment: 'client' }); const counter = telemetry.registerCounter({ library: LibraryTraces_Library.LIBRARY_CONFIDENCE, version: '9.9.9', @@ -61,7 +61,7 @@ describe('Telemetry', () => { }); it('monitoring gets cleared after snapshot is obtained', () => { - const telemetry = new Telemetry({ disabled: false, logger: { warn: jest.fn() } }); + const telemetry = new Telemetry({ disabled: false, logger: { warn: jest.fn() }, environment: 'client' }); const counter = telemetry.registerCounter({ library: LibraryTraces_Library.LIBRARY_CONFIDENCE, version: '9.9.9', diff --git a/packages/sdk/src/Telemetry.ts b/packages/sdk/src/Telemetry.ts index a496e20..3f7d70d 100644 --- a/packages/sdk/src/Telemetry.ts +++ b/packages/sdk/src/Telemetry.ts @@ -4,10 +4,11 @@ import { LibraryTraces_Trace, LibraryTraces_TraceId, Monitoring, + Platform, } from './generated/confidence/telemetry/v1/telemetry'; import { Logger } from './logger'; -export type TelemetryOptions = { disabled: boolean; logger: Logger }; +export type TelemetryOptions = { disabled: boolean; logger: Logger; environment: 'backend' | 'client' }; export type Tag = { library: LibraryTraces_Library; @@ -22,10 +23,12 @@ export class Telemetry { private readonly disabled: boolean; private readonly logger: Logger; private readonly libraryTraces: LibraryTraces[] = []; + private readonly platform: Platform; constructor(opts: TelemetryOptions) { this.disabled = opts.disabled; this.logger = opts.logger; + this.platform = opts.environment === 'client' ? Platform.PLATFORM_JS_WEB : Platform.PLATFORM_JS_SERVER; } private registerLibraryTraces({ library, version, id }: Tag): TraceConsumer { @@ -65,6 +68,6 @@ export class Telemetry { libraryVersion, traces: traces.splice(0, traces.length), })); - return { libraryTraces }; + return { libraryTraces, platform: this.platform }; } } diff --git a/packages/sdk/src/generated/confidence/telemetry/v1/telemetry.ts b/packages/sdk/src/generated/confidence/telemetry/v1/telemetry.ts index aabaf6b..36c4e0d 100644 --- a/packages/sdk/src/generated/confidence/telemetry/v1/telemetry.ts +++ b/packages/sdk/src/generated/confidence/telemetry/v1/telemetry.ts @@ -9,8 +9,102 @@ import { BinaryWriter } from '@bufbuild/protobuf/wire'; export const protobufPackage = 'confidence.telemetry.v1'; +export enum Platform { + PLATFORM_UNSPECIFIED = 0, + PLATFORM_JAVA = 1, + PLATFORM_KOTLIN = 2, + PLATFORM_SWIFT = 3, + PLATFORM_JS_WEB = 4, + PLATFORM_JS_SERVER = 5, + PLATFORM_PYTHON = 6, + PLATFORM_GO = 7, + PLATFORM_RUBY = 8, + PLATFORM_RUST = 9, + PLATFORM_FLUTTER_IOS = 10, + PLATFORM_FLUTTER_ANDROID = 11, + UNRECOGNIZED = -1, +} + +export function platformFromJSON(object: any): Platform { + switch (object) { + case 0: + case 'PLATFORM_UNSPECIFIED': + return Platform.PLATFORM_UNSPECIFIED; + case 1: + case 'PLATFORM_JAVA': + return Platform.PLATFORM_JAVA; + case 2: + case 'PLATFORM_KOTLIN': + return Platform.PLATFORM_KOTLIN; + case 3: + case 'PLATFORM_SWIFT': + return Platform.PLATFORM_SWIFT; + case 4: + case 'PLATFORM_JS_WEB': + return Platform.PLATFORM_JS_WEB; + case 5: + case 'PLATFORM_JS_SERVER': + return Platform.PLATFORM_JS_SERVER; + case 6: + case 'PLATFORM_PYTHON': + return Platform.PLATFORM_PYTHON; + case 7: + case 'PLATFORM_GO': + return Platform.PLATFORM_GO; + case 8: + case 'PLATFORM_RUBY': + return Platform.PLATFORM_RUBY; + case 9: + case 'PLATFORM_RUST': + return Platform.PLATFORM_RUST; + case 10: + case 'PLATFORM_FLUTTER_IOS': + return Platform.PLATFORM_FLUTTER_IOS; + case 11: + case 'PLATFORM_FLUTTER_ANDROID': + return Platform.PLATFORM_FLUTTER_ANDROID; + case -1: + case 'UNRECOGNIZED': + default: + return Platform.UNRECOGNIZED; + } +} + +export function platformToJSON(object: Platform): string { + switch (object) { + case Platform.PLATFORM_UNSPECIFIED: + return 'PLATFORM_UNSPECIFIED'; + case Platform.PLATFORM_JAVA: + return 'PLATFORM_JAVA'; + case Platform.PLATFORM_KOTLIN: + return 'PLATFORM_KOTLIN'; + case Platform.PLATFORM_SWIFT: + return 'PLATFORM_SWIFT'; + case Platform.PLATFORM_JS_WEB: + return 'PLATFORM_JS_WEB'; + case Platform.PLATFORM_JS_SERVER: + return 'PLATFORM_JS_SERVER'; + case Platform.PLATFORM_PYTHON: + return 'PLATFORM_PYTHON'; + case Platform.PLATFORM_GO: + return 'PLATFORM_GO'; + case Platform.PLATFORM_RUBY: + return 'PLATFORM_RUBY'; + case Platform.PLATFORM_RUST: + return 'PLATFORM_RUST'; + case Platform.PLATFORM_FLUTTER_IOS: + return 'PLATFORM_FLUTTER_IOS'; + case Platform.PLATFORM_FLUTTER_ANDROID: + return 'PLATFORM_FLUTTER_ANDROID'; + case Platform.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + export interface Monitoring { libraryTraces: LibraryTraces[]; + platform: Platform; } export interface LibraryTraces { @@ -126,6 +220,9 @@ export const Monitoring: MessageFns = { for (const v of message.libraryTraces) { LibraryTraces.encode(v!, writer.uint32(10).fork()).join(); } + if (message.platform !== 0) { + writer.uint32(16).int32(message.platform); + } return writer; }, @@ -134,6 +231,7 @@ export const Monitoring: MessageFns = { libraryTraces: globalThis.Array.isArray(object?.libraryTraces) ? object.libraryTraces.map((e: any) => LibraryTraces.fromJSON(e)) : [], + platform: isSet(object.platform) ? platformFromJSON(object.platform) : 0, }; }, @@ -142,6 +240,9 @@ export const Monitoring: MessageFns = { if (message.libraryTraces?.length) { obj.libraryTraces = message.libraryTraces.map(e => LibraryTraces.toJSON(e)); } + if (message.platform !== 0) { + obj.platform = platformToJSON(message.platform); + } return obj; }, };