diff --git a/.changeset/tricky-kids-look.md b/.changeset/tricky-kids-look.md new file mode 100644 index 0000000..e7de22f --- /dev/null +++ b/.changeset/tricky-kids-look.md @@ -0,0 +1,5 @@ +--- +"workers-tracing": patch +--- + +Fixed #9 - if `navigator` is not defined (old compat date) it will now default to "Unknown" for the runtime name. diff --git a/src/tracing.ts b/src/tracing.ts index a36a32c..96a56e9 100644 --- a/src/tracing.ts +++ b/src/tracing.ts @@ -24,7 +24,10 @@ export function getDefaultAttributes(opts: TracerOptions): Attributes { [ATTRIBUTE_NAME.SDK_NAME]: 'workers-tracing', [ATTRIBUTE_NAME.SDK_LANG]: 'javascript', [ATTRIBUTE_NAME.SDK_VERSION]: '__VERSION__', - [ATTRIBUTE_NAME.RUNTIME_NAME]: navigator.userAgent, // Cloudflare-Workers + [ATTRIBUTE_NAME.RUNTIME_NAME]: + typeof navigator !== 'undefined' && navigator.userAgent // Cloudflare-Workers + ? navigator.userAgent + : 'Unknown', }; } diff --git a/test/api.test.ts b/test/api.test.ts index cb1c6f9..2bcae87 100644 --- a/test/api.test.ts +++ b/test/api.test.ts @@ -362,4 +362,84 @@ describe('API', () => { }); }); }); + + describe('Default attributes', () => { + test('Attributes are all set', async () => { + devWorker = await startWorker('test/scripts/api/root-span.ts'); + + const res = await devWorker.fetch('http://worker/test'); + + expect(res.status).toBe(200); + expect(res.headers.get('x-trace-id')).not.toBeNull(); + + const traceId = res.headers.get('x-trace-id'); + if (traceId === null) { + expect(traceId).not.toBeNull(); + return; + } + const trace = await getTrace(collectorWorker, traceId); + + expect(trace.resourceSpans.length).toBe(1); + const resourceSpan = trace.resourceSpans[0]; + const resource = resourceSpan.resource; + + // Validate default attributes + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SERVICE_NAME), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SERVICE_NAME, value: { stringValue: 'root-span' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SDK_NAME), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SDK_NAME, value: { stringValue: 'workers-tracing' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SDK_LANG), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SDK_LANG, value: { stringValue: 'javascript' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SDK_VERSION), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SDK_VERSION, value: { stringValue: '__VERSION__' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.RUNTIME_NAME), + ).toStrictEqual({ key: ATTRIBUTE_NAME.RUNTIME_NAME, value: { stringValue: 'Cloudflare-Workers' } }); + }); + + test('Attributes work with no compat date', async () => { + devWorker = await startWorker('test/scripts/api/root-span.ts', { + // Set compat date to September 2021, this is the earliest compat date possible + // and what it will default to if none is provided + compatibilityDate: '2021-09-14', + }); + + const res = await devWorker.fetch('http://worker/test'); + + expect(res.status).toBe(200); + expect(res.headers.get('x-trace-id')).not.toBeNull(); + + const traceId = res.headers.get('x-trace-id'); + if (traceId === null) { + expect(traceId).not.toBeNull(); + return; + } + const trace = await getTrace(collectorWorker, traceId); + + expect(trace.resourceSpans.length).toBe(1); + const resourceSpan = trace.resourceSpans[0]; + const resource = resourceSpan.resource; + + // Validate default attributes + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SERVICE_NAME), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SERVICE_NAME, value: { stringValue: 'root-span' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SDK_NAME), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SDK_NAME, value: { stringValue: 'workers-tracing' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SDK_LANG), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SDK_LANG, value: { stringValue: 'javascript' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.SDK_VERSION), + ).toStrictEqual({ key: ATTRIBUTE_NAME.SDK_VERSION, value: { stringValue: '__VERSION__' } }); + expect( + resource.attributes.find((attribute) => attribute.key === ATTRIBUTE_NAME.RUNTIME_NAME), + ).toStrictEqual({ key: ATTRIBUTE_NAME.RUNTIME_NAME, value: { stringValue: 'Unknown' } }); + }); + }); });