From ac7d12f8f6cb900eff7a03c9e3e16dbde5ce5e79 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 8 Apr 2025 10:58:36 +0200 Subject: [PATCH] feat(core): Add sdk name and version to logs --- .../public-api/logger/integration/test.ts | 84 +++++++++ .../suites/public-api/logger/simple/test.ts | 162 +++++++++++++++++- packages/core/src/logs/exports.ts | 6 + packages/core/test/lib/logs/exports.test.ts | 45 +++++ 4 files changed, 291 insertions(+), 6 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts b/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts index 183c80eb35be..e255a6afda23 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts @@ -30,6 +30,18 @@ sentryTest('should capture console object calls', async ({ getLocalTestUrl, page stringValue: 'auto.console.logging', }, }, + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, ], timeUnixNano: expect.any(String), traceId: expect.any(String), @@ -51,6 +63,18 @@ sentryTest('should capture console object calls', async ({ getLocalTestUrl, page stringValue: 'auto.console.logging', }, }, + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, ], timeUnixNano: expect.any(String), traceId: expect.any(String), @@ -72,6 +96,18 @@ sentryTest('should capture console object calls', async ({ getLocalTestUrl, page stringValue: 'auto.console.logging', }, }, + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, ], timeUnixNano: expect.any(String), traceId: expect.any(String), @@ -93,6 +129,18 @@ sentryTest('should capture console object calls', async ({ getLocalTestUrl, page stringValue: 'auto.console.logging', }, }, + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, ], timeUnixNano: expect.any(String), traceId: expect.any(String), @@ -114,6 +162,18 @@ sentryTest('should capture console object calls', async ({ getLocalTestUrl, page stringValue: 'auto.console.logging', }, }, + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, ], timeUnixNano: expect.any(String), traceId: expect.any(String), @@ -135,6 +195,18 @@ sentryTest('should capture console object calls', async ({ getLocalTestUrl, page stringValue: 'auto.console.logging', }, }, + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, ], timeUnixNano: expect.any(String), traceId: expect.any(String), @@ -156,6 +228,18 @@ sentryTest('should capture console object calls', async ({ getLocalTestUrl, page stringValue: 'auto.console.logging', }, }, + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, ], timeUnixNano: expect.any(String), traceId: expect.any(String), diff --git a/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts b/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts index f19dbe3a5a5b..5995058867a0 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts @@ -23,7 +23,20 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page { severityText: 'trace', body: { stringValue: 'test trace' }, - attributes: [], + attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, + ], timeUnixNano: expect.any(String), traceId: expect.any(String), severityNumber: 1, @@ -37,7 +50,20 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page { severityText: 'debug', body: { stringValue: 'test debug' }, - attributes: [], + attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, + ], timeUnixNano: expect.any(String), traceId: expect.any(String), severityNumber: 5, @@ -51,7 +77,20 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page { severityText: 'info', body: { stringValue: 'test info' }, - attributes: [], + attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, + ], timeUnixNano: expect.any(String), traceId: expect.any(String), severityNumber: 9, @@ -65,7 +104,20 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page { severityText: 'warn', body: { stringValue: 'test warn' }, - attributes: [], + attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, + ], timeUnixNano: expect.any(String), traceId: expect.any(String), severityNumber: 13, @@ -79,7 +131,20 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page { severityText: 'error', body: { stringValue: 'test error' }, - attributes: [], + attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, + ], timeUnixNano: expect.any(String), traceId: expect.any(String), severityNumber: 17, @@ -93,7 +158,20 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page { severityText: 'fatal', body: { stringValue: 'test fatal' }, - attributes: [], + attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, + ], timeUnixNano: expect.any(String), traceId: expect.any(String), severityNumber: 21, @@ -108,6 +186,18 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page severityText: 'trace', body: { stringValue: 'test trace stringArg false 123' }, attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, { key: 'sentry.message.template', value: { @@ -153,6 +243,18 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page severityText: 'debug', body: { stringValue: 'test debug stringArg false 123' }, attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, { key: 'sentry.message.template', value: { @@ -198,6 +300,18 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page severityText: 'info', body: { stringValue: 'test info stringArg false 123' }, attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, { key: 'sentry.message.template', value: { @@ -243,6 +357,18 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page severityText: 'warn', body: { stringValue: 'test warn stringArg false 123' }, attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, { key: 'sentry.message.template', value: { @@ -288,6 +414,18 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page severityText: 'error', body: { stringValue: 'test error stringArg false 123' }, attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, { key: 'sentry.message.template', value: { @@ -333,6 +471,18 @@ sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page severityText: 'fatal', body: { stringValue: 'test fatal stringArg false 123' }, attributes: [ + { + key: 'sentry.sdk.name', + value: { + stringValue: 'sentry.javascript.browser', + }, + }, + { + key: 'sentry.sdk.version', + value: { + stringValue: expect.any(String), + }, + }, { key: 'sentry.message.template', value: { diff --git a/packages/core/src/logs/exports.ts b/packages/core/src/logs/exports.ts index 9ef63da838dc..8b5f0c76bc17 100644 --- a/packages/core/src/logs/exports.ts +++ b/packages/core/src/logs/exports.ts @@ -104,6 +104,12 @@ export function _INTERNAL_captureLog( logAttributes['sentry.environment'] = environment; } + const { sdk } = client.getSdkMetadata() ?? {}; + if (sdk) { + logAttributes['sentry.sdk.name'] = sdk.name; + logAttributes['sentry.sdk.version'] = sdk.version; + } + if (isParameterizedString(message)) { const { __sentry_template_string__, __sentry_template_values__ = [] } = message; logAttributes['sentry.message.template'] = __sentry_template_string__; diff --git a/packages/core/test/lib/logs/exports.test.ts b/packages/core/test/lib/logs/exports.test.ts index eb3da694fdd4..c672373df947 100644 --- a/packages/core/test/lib/logs/exports.test.ts +++ b/packages/core/test/lib/logs/exports.test.ts @@ -142,6 +142,51 @@ describe('_INTERNAL_captureLog', () => { ); }); + it('includes SDK metadata in log attributes when available', () => { + const options = getDefaultTestClientOptions({ + dsn: PUBLIC_DSN, + _experiments: { enableLogs: true }, + }); + const client = new TestClient(options); + // Mock getSdkMetadata to return SDK info + vi.spyOn(client, 'getSdkMetadata').mockReturnValue({ + sdk: { + name: 'sentry.javascript.node', + version: '7.0.0', + }, + }); + + _INTERNAL_captureLog({ level: 'info', message: 'test log with SDK metadata' }, client, undefined); + + const logAttributes = _INTERNAL_getLogBuffer(client)?.[0]?.attributes; + expect(logAttributes).toEqual( + expect.arrayContaining([ + expect.objectContaining({ key: 'sentry.sdk.name', value: { stringValue: 'sentry.javascript.node' } }), + expect.objectContaining({ key: 'sentry.sdk.version', value: { stringValue: '7.0.0' } }), + ]), + ); + }); + + it('does not include SDK metadata in log attributes when not available', () => { + const options = getDefaultTestClientOptions({ + dsn: PUBLIC_DSN, + _experiments: { enableLogs: true }, + }); + const client = new TestClient(options); + // Mock getSdkMetadata to return no SDK info + vi.spyOn(client, 'getSdkMetadata').mockReturnValue({}); + + _INTERNAL_captureLog({ level: 'info', message: 'test log without SDK metadata' }, client, undefined); + + const logAttributes = _INTERNAL_getLogBuffer(client)?.[0]?.attributes; + expect(logAttributes).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ key: 'sentry.sdk.name' }), + expect.objectContaining({ key: 'sentry.sdk.version' }), + ]), + ); + }); + it('includes custom attributes in log', () => { const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, _experiments: { enableLogs: true } }); const client = new TestClient(options);