diff --git a/apps/nextjs/src/app/api/chat/chatHandler.ts b/apps/nextjs/src/app/api/chat/chatHandler.ts index 1d79bc5f7..ea63c4ecd 100644 --- a/apps/nextjs/src/app/api/chat/chatHandler.ts +++ b/apps/nextjs/src/app/api/chat/chatHandler.ts @@ -66,7 +66,10 @@ function reportErrorTelemetry( error: Error, errorType: string, statusMessage: string, - additionalAttributes: Record = {}, + additionalAttributes: Record< + string, + string | number | boolean | undefined + > = {}, ) { span.setTag("error", true); span.setTag("error.type", errorType); diff --git a/apps/nextjs/src/app/api/chat/config.ts b/apps/nextjs/src/app/api/chat/config.ts index 5ffe10205..53625f0e8 100644 --- a/apps/nextjs/src/app/api/chat/config.ts +++ b/apps/nextjs/src/app/api/chat/config.ts @@ -1,5 +1,4 @@ import { Aila, AilaInitializationOptions } from "@oakai/aila"; -import { TracingSpan } from "@oakai/core/src/tracing/serverTracing"; import { prisma as globalPrisma, type PrismaClientWithAccelerate, diff --git a/apps/nextjs/src/utils/testHelpers/tracing.ts b/apps/nextjs/src/utils/testHelpers/tracing.ts index e65154d5d..e3d3633de 100644 --- a/apps/nextjs/src/utils/testHelpers/tracing.ts +++ b/apps/nextjs/src/utils/testHelpers/tracing.ts @@ -18,7 +18,7 @@ export function expectTracingSpan(operationName: string) { ).toBeFalsy(); }, }, - toHaveBeenExecutedWith: (expectedTags: Record) => { + toHaveBeenExecutedWith: (expectedTags: Record) => { const span = mockTracer.spans.find( (span) => span.tags["operation.name"] === operationName, ); diff --git a/packages/core/src/tracing/mockTracer.ts b/packages/core/src/tracing/mockTracer.ts index a5a4dda54..9b645708d 100644 --- a/packages/core/src/tracing/mockTracer.ts +++ b/packages/core/src/tracing/mockTracer.ts @@ -1,8 +1,8 @@ import { TracingSpan } from "./serverTracing"; class MockSpan implements TracingSpan { - tags: Record = {}; - setTag(key: string, value: any) { + tags: Record = {}; + setTag(key: string, value: string | number | boolean | undefined) { this.tags[key] = value; } finish() {} @@ -13,8 +13,8 @@ class MockTracer { trace( name: string, - options: any, - callback: (span: TracingSpan) => Promise, + options: Record, + callback: (span: TracingSpan) => Promise, ) { const span = new MockSpan(); span.setTag("operation.name", name); diff --git a/packages/core/src/tracing/serverTracing.ts b/packages/core/src/tracing/serverTracing.ts index 06da0f30a..b851a0037 100644 --- a/packages/core/src/tracing/serverTracing.ts +++ b/packages/core/src/tracing/serverTracing.ts @@ -4,7 +4,7 @@ import { mockTracer } from "./mockTracer"; initializeTracer({}); export interface TracingSpan { - setTag: (key: string, value: any) => void; + setTag: (key: string, value: string | number | boolean | undefined) => void; finish: () => void; } @@ -13,17 +13,29 @@ export const tracer = isTest : (baseTracer as unknown as { trace: ( name: string, - options: any, - callback: (span: TracingSpan) => Promise, - ) => Promise; + options: Record, + callback: (span: TracingSpan) => Promise, + ) => Promise; }); export function withTelemetry( operationName: string, - options: Record, + options: Record, handler: (span: TracingSpan) => Promise, ): Promise { - return tracer.trace(operationName, options, async (span) => { + const stringifiedOptions: Record = Object.entries( + options, + ).reduce((acc, [key, value]) => { + if (value !== undefined) { + return { + ...acc, + [key]: typeof value === "boolean" ? value.toString() : value, + }; + } + return acc; + }, {}); + + return tracer.trace(operationName, stringifiedOptions, async (span) => { try { return await handler(span); } catch (error) { @@ -31,7 +43,9 @@ export function withTelemetry( if (error instanceof Error) { span.setTag("error_type", error.constructor.name); span.setTag("error_message", error.message); - span.setTag("error_stack", error.stack); + if (error.stack) { + span.setTag("error_stack", error.stack); + } } else { span.setTag("error_message", String(error)); } @@ -39,5 +53,5 @@ export function withTelemetry( } finally { span.finish(); } - }); + }) as Promise; }