Skip to content

Commit

Permalink
fix: wip telemetry singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklasl committed Nov 21, 2024
1 parent ed4f281 commit ac1590a
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 31 deletions.
3 changes: 2 additions & 1 deletion api/sdk.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver {
//
// @internal
readonly contextChanges: Subscribe<string[]>;
static create({ clientSecret, region, timeout, environment, fetchImplementation, logger, resolveBaseUrl, }: ConfidenceOptions): Confidence;
static create({ clientSecret, region, timeout, environment, fetchImplementation, logger, resolveBaseUrl, disableTelemetry, }: ConfidenceOptions): Confidence;
get environment(): string;
evaluateFlag(path: string, defaultValue: string): FlagEvaluation<string>;
// (undocumented)
Expand Down Expand Up @@ -55,6 +55,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver {
// @public
export interface ConfidenceOptions {
clientSecret: string;
disableTelemetry?: boolean;
environment: 'client' | 'backend';
// Warning: (ae-forgotten-export) The symbol "SimpleFetch" needs to be exported by the entry point index.d.ts
fetchImplementation?: SimpleFetch;
Expand Down
8 changes: 4 additions & 4 deletions packages/sdk/src/Confidence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export interface ConfidenceOptions {
logger?: Logger;
/** Sets an alternative resolve url */
resolveBaseUrl?: string;
/** Enable telemetry */
enableTelemetry?: boolean;
/** Disable telemetry */
disableTelemetry?: boolean;
}

/**
Expand Down Expand Up @@ -335,7 +335,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver {
fetchImplementation = defaultFetchImplementation(),
logger = defaultLogger(),
resolveBaseUrl,
enableTelemetry = true,
disableTelemetry = false,
}: ConfidenceOptions): Confidence {
const sdk = {
id: SdkId.SDK_ID_JS_CONFIDENCE,
Expand All @@ -349,7 +349,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver {
resolveTimeout: timeout,
region,
resolveBaseUrl,
enableTelemetry,
disableTelemetry,
});
if (environment === 'client') {
flagResolverClient = new CachingFlagResolverClient(flagResolverClient, Number.POSITIVE_INFINITY);
Expand Down
37 changes: 11 additions & 26 deletions packages/sdk/src/FlagResolverClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FlagEvaluation } from '.';
import { AccessiblePromise } from './AccessiblePromise';
import { Applier, FlagResolution } from './FlagResolution';
import Telemetry from './Telemetry';
import { Value } from './Value';
import { Context } from './context';
import { FetchBuilder, TimeUnit } from './fetch-util';
Expand All @@ -11,20 +12,13 @@ import {
AppliedFlag,
} from './generated/confidence/flags/resolver/v1/api';
import { Sdk } from './generated/confidence/flags/resolver/v1/types';
import {
LibraryTraces_Library,
LibraryTraces_TraceId,
Monitoring,
} from './generated/confidence/telemetry/v1/telemetry';
import { Monitoring } from './generated/confidence/telemetry/v1/telemetry';
import { SimpleFetch } from './types';

const FLAG_PREFIX = 'flags/';

export class ResolveError extends Error {
constructor(
public readonly code: FlagEvaluation.ErrorCode,
message: string,
) {
constructor(public readonly code: FlagEvaluation.ErrorCode, message: string) {
super(message);
}
}
Expand Down Expand Up @@ -93,7 +87,7 @@ export type FlagResolverClientOptions = {
environment: 'client' | 'backend';
region?: 'eu' | 'us';
resolveBaseUrl?: string;
enableTelemetry: boolean;
disableTelemetry: boolean;
};

export class FetchingFlagResolverClient implements FlagResolverClient {
Expand All @@ -114,9 +108,9 @@ export class FetchingFlagResolverClient implements FlagResolverClient {
environment,
region,
resolveBaseUrl,
enableTelemetry,
disableTelemetry,
}: FlagResolverClientOptions) {
if (!enableTelemetry) {
if (disableTelemetry) {
// TODO think about both resolve and apply request logic for backends
this.fetchImplementation =
environment === 'backend' ? fetchImplementation : withRequestLogic(fetchImplementation);
Expand Down Expand Up @@ -152,13 +146,17 @@ export class FetchingFlagResolverClient implements FlagResolverClient {
this.resolveTimeout,
new ResolveError('TIMEOUT', 'Resolve timeout'),
);
const start = new Date().getTime();
return this.resolveFlagsJson(request, signalWithTimeout)
.then(response => FlagResolution.ready(context, response, this.createApplier(response.resolveToken)))
.catch(error => {
if (error instanceof ResolveError) {
return FlagResolution.failed(context, error.code, error.message);
}
throw error;
})
.finally(() => {
Telemetry.getInstance().markFlagResolved(new Date().getTime() - start);
});
});
}
Expand Down Expand Up @@ -297,20 +295,7 @@ export function withTelemetryData(fetchImplementation: (request: Request) => Pro
return new FetchBuilder()
.modifyRequest(async request => {
// TODO pull actual telemetry data
const monitoring: Monitoring = {
libraryTraces: [
{
library: LibraryTraces_Library.LIBRARY_CONFIDENCE,
libraryVersion: '0.1.0',
traces: [
{
id: LibraryTraces_TraceId.TRACE_ID_RESOLVE_LATENCY,
millisecondDuration: 100,
},
],
},
],
};
const monitoring: Monitoring = Telemetry.getInstance().getSnapshot();
const headers = new Headers(request.headers);
const base64Message = btoa(String.fromCharCode(...Monitoring.encode(monitoring).finish()));

Expand Down
67 changes: 67 additions & 0 deletions packages/sdk/src/Telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {
LibraryTraces_Library,
LibraryTraces_TraceId,
Monitoring,
} from './generated/confidence/telemetry/v1/telemetry';

class Telemetry {
private static instance: Telemetry;
private monitoring: Monitoring = {
libraryTraces: [],
};

static getInstance(): Telemetry {
if (!Telemetry.instance) {
Telemetry.instance = new Telemetry();
}
return Telemetry.instance;
}

markStaleFlag(): void {
this.pushTrace(LibraryTraces_TraceId.TRACE_ID_STALE_FLAG);
}

pushTrace(traceId: LibraryTraces_TraceId, latency: number | undefined = undefined): void {
const { library, version } = this.getLibraryAndVersion();
const existing = this.monitoring.libraryTraces.find(trace => {
return trace.library === library && trace.libraryVersion === version;
});
if (existing) {
existing.traces.push({
id: traceId,
millisecondDuration: latency,
});
} else {
this.monitoring.libraryTraces.push({
library,
libraryVersion: version,
traces: [
{
id: traceId,
millisecondDuration: latency,
},
],
});
}
}

getLibraryAndVersion(): { library: LibraryTraces_Library; version: string } {
// TODO - get the library and version somehow
return {
library: LibraryTraces_Library.LIBRARY_CONFIDENCE,
version: '0.0.0',
};
}

markFlagResolved(latency: number): void {
this.pushTrace(LibraryTraces_TraceId.TRACE_ID_RESOLVE_LATENCY, latency);
}

getSnapshot(): Monitoring {
const snapshot = { ...this.monitoring };
this.monitoring = { libraryTraces: [] }; // Reset the state
return snapshot;
}
}

export default Telemetry;

0 comments on commit ac1590a

Please sign in to comment.