Skip to content

Commit a3c43dd

Browse files
committed
feat(logs): Ensure client & scope can be passed to log functions
1 parent 2a7a74b commit a3c43dd

File tree

4 files changed

+347
-143
lines changed

4 files changed

+347
-143
lines changed

packages/browser/src/log.ts

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Log, LogSeverityLevel, ParameterizedString } from '@sentry/core';
1+
import type { Client, Log, LogSeverityLevel, ParameterizedString, Scope } from '@sentry/core';
22
import { _INTERNAL_captureLog } from '@sentry/core';
33

44
/**
@@ -13,9 +13,10 @@ function captureLog(
1313
level: LogSeverityLevel,
1414
message: ParameterizedString,
1515
attributes?: Log['attributes'],
16-
severityNumber?: Log['severityNumber'],
16+
client?: Client,
17+
scope?: Scope,
1718
): void {
18-
_INTERNAL_captureLog({ level, message, attributes, severityNumber });
19+
_INTERNAL_captureLog({ level, message, attributes }, client, scope);
1920
}
2021

2122
/**
@@ -43,8 +44,13 @@ function captureLog(
4344
* });
4445
* ```
4546
*/
46-
export function trace(message: ParameterizedString, attributes?: Log['attributes']): void {
47-
captureLog('trace', message, attributes);
47+
export function trace(
48+
message: ParameterizedString,
49+
attributes?: Log['attributes'],
50+
client?: Client,
51+
scope?: Scope,
52+
): void {
53+
captureLog('trace', message, attributes, client, scope);
4854
}
4955

5056
/**
@@ -73,8 +79,13 @@ export function trace(message: ParameterizedString, attributes?: Log['attributes
7379
* });
7480
* ```
7581
*/
76-
export function debug(message: ParameterizedString, attributes?: Log['attributes']): void {
77-
captureLog('debug', message, attributes);
82+
export function debug(
83+
message: ParameterizedString,
84+
attributes?: Log['attributes'],
85+
client?: Client,
86+
scope?: Scope,
87+
): void {
88+
captureLog('debug', message, attributes, client, scope);
7889
}
7990

8091
/**
@@ -103,8 +114,13 @@ export function debug(message: ParameterizedString, attributes?: Log['attributes
103114
* });
104115
* ```
105116
*/
106-
export function info(message: ParameterizedString, attributes?: Log['attributes']): void {
107-
captureLog('info', message, attributes);
117+
export function info(
118+
message: ParameterizedString,
119+
attributes?: Log['attributes'],
120+
client?: Client,
121+
scope?: Scope,
122+
): void {
123+
captureLog('info', message, attributes, client, scope);
108124
}
109125

110126
/**
@@ -134,8 +150,13 @@ export function info(message: ParameterizedString, attributes?: Log['attributes'
134150
* });
135151
* ```
136152
*/
137-
export function warn(message: ParameterizedString, attributes?: Log['attributes']): void {
138-
captureLog('warn', message, attributes);
153+
export function warn(
154+
message: ParameterizedString,
155+
attributes?: Log['attributes'],
156+
client?: Client,
157+
scope?: Scope,
158+
): void {
159+
captureLog('warn', message, attributes, client, scope);
139160
}
140161

141162
/**
@@ -166,8 +187,13 @@ export function warn(message: ParameterizedString, attributes?: Log['attributes'
166187
* });
167188
* ```
168189
*/
169-
export function error(message: ParameterizedString, attributes?: Log['attributes']): void {
170-
captureLog('error', message, attributes);
190+
export function error(
191+
message: ParameterizedString,
192+
attributes?: Log['attributes'],
193+
client?: Client,
194+
scope?: Scope,
195+
): void {
196+
captureLog('error', message, attributes, client, scope);
171197
}
172198

173199
/**
@@ -198,8 +224,13 @@ export function error(message: ParameterizedString, attributes?: Log['attributes
198224
* });
199225
* ```
200226
*/
201-
export function fatal(message: ParameterizedString, attributes?: Log['attributes']): void {
202-
captureLog('fatal', message, attributes);
227+
export function fatal(
228+
message: ParameterizedString,
229+
attributes?: Log['attributes'],
230+
client?: Client,
231+
scope?: Scope,
232+
): void {
233+
captureLog('fatal', message, attributes, client, scope);
203234
}
204235

205236
export { fmt } from '@sentry/core';

packages/browser/test/log.test.ts

Lines changed: 105 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import * as sentryCore from '@sentry/core';
66
import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core';
77
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8-
import { init, logger } from '../src';
8+
import { BrowserClient, init, logger } from '../src';
9+
import { getDefaultBrowserClientOptions } from './helper/browser-client-options';
910
import { makeSimpleTransport } from './mocks/simpletransport';
1011

1112
const dsn = 'https://[email protected]/4291';
@@ -66,87 +67,138 @@ describe('Logger', () => {
6667

6768
it('should call _INTERNAL_captureLog with trace level', () => {
6869
logger.trace('Test trace message', { key: 'value' });
69-
expect(mockCaptureLog).toHaveBeenCalledWith({
70-
level: 'trace',
71-
message: 'Test trace message',
72-
attributes: { key: 'value' },
73-
severityNumber: undefined,
74-
});
70+
expect(mockCaptureLog).toHaveBeenCalledWith(
71+
{
72+
level: 'trace',
73+
message: 'Test trace message',
74+
attributes: { key: 'value' },
75+
severityNumber: undefined,
76+
},
77+
undefined,
78+
undefined,
79+
);
7580
});
7681

7782
it('should call _INTERNAL_captureLog with debug level', () => {
7883
logger.debug('Test debug message', { key: 'value' });
79-
expect(mockCaptureLog).toHaveBeenCalledWith({
80-
level: 'debug',
81-
message: 'Test debug message',
82-
attributes: { key: 'value' },
83-
severityNumber: undefined,
84-
});
84+
expect(mockCaptureLog).toHaveBeenCalledWith(
85+
{
86+
level: 'debug',
87+
message: 'Test debug message',
88+
attributes: { key: 'value' },
89+
severityNumber: undefined,
90+
},
91+
undefined,
92+
undefined,
93+
);
8594
});
8695

8796
it('should call _INTERNAL_captureLog with info level', () => {
8897
logger.info('Test info message', { key: 'value' });
89-
expect(mockCaptureLog).toHaveBeenCalledWith({
90-
level: 'info',
91-
message: 'Test info message',
92-
attributes: { key: 'value' },
93-
severityNumber: undefined,
94-
});
98+
expect(mockCaptureLog).toHaveBeenCalledWith(
99+
{
100+
level: 'info',
101+
message: 'Test info message',
102+
attributes: { key: 'value' },
103+
severityNumber: undefined,
104+
},
105+
undefined,
106+
undefined,
107+
);
95108
});
96109

97110
it('should call _INTERNAL_captureLog with warn level', () => {
98111
logger.warn('Test warn message', { key: 'value' });
99-
expect(mockCaptureLog).toHaveBeenCalledWith({
100-
level: 'warn',
101-
message: 'Test warn message',
102-
attributes: { key: 'value' },
103-
severityNumber: undefined,
104-
});
112+
expect(mockCaptureLog).toHaveBeenCalledWith(
113+
{
114+
level: 'warn',
115+
message: 'Test warn message',
116+
attributes: { key: 'value' },
117+
severityNumber: undefined,
118+
},
119+
undefined,
120+
undefined,
121+
);
105122
});
106123

107124
it('should call _INTERNAL_captureLog with error level', () => {
108125
logger.error('Test error message', { key: 'value' });
109-
expect(mockCaptureLog).toHaveBeenCalledWith({
110-
level: 'error',
111-
message: 'Test error message',
112-
attributes: { key: 'value' },
113-
severityNumber: undefined,
114-
});
126+
expect(mockCaptureLog).toHaveBeenCalledWith(
127+
{
128+
level: 'error',
129+
message: 'Test error message',
130+
attributes: { key: 'value' },
131+
severityNumber: undefined,
132+
},
133+
undefined,
134+
undefined,
135+
);
115136
});
116137

117138
it('should call _INTERNAL_captureLog with fatal level', () => {
118139
logger.fatal('Test fatal message', { key: 'value' });
119-
expect(mockCaptureLog).toHaveBeenCalledWith({
120-
level: 'fatal',
121-
message: 'Test fatal message',
122-
attributes: { key: 'value' },
123-
severityNumber: undefined,
124-
});
140+
expect(mockCaptureLog).toHaveBeenCalledWith(
141+
{
142+
level: 'fatal',
143+
message: 'Test fatal message',
144+
attributes: { key: 'value' },
145+
severityNumber: undefined,
146+
},
147+
undefined,
148+
undefined,
149+
);
125150
});
126151
});
127152

128153
it('should handle parameterized strings with parameters', () => {
129154
logger.info(logger.fmt`Hello ${'John'}, your balance is ${100}`, { userId: 123 });
130-
expect(mockCaptureLog).toHaveBeenCalledWith({
131-
level: 'info',
132-
message: expect.objectContaining({
133-
__sentry_template_string__: 'Hello %s, your balance is %s',
134-
__sentry_template_values__: ['John', 100],
135-
}),
136-
attributes: {
137-
userId: 123,
155+
expect(mockCaptureLog).toHaveBeenCalledWith(
156+
{
157+
level: 'info',
158+
message: expect.objectContaining({
159+
__sentry_template_string__: 'Hello %s, your balance is %s',
160+
__sentry_template_values__: ['John', 100],
161+
}),
162+
attributes: {
163+
userId: 123,
164+
},
138165
},
139-
});
166+
undefined,
167+
undefined,
168+
);
140169
});
141170

142171
it('should handle parameterized strings without additional attributes', () => {
143172
logger.debug(logger.fmt`User ${'Alice'} logged in from ${'mobile'}`);
144-
expect(mockCaptureLog).toHaveBeenCalledWith({
145-
level: 'debug',
146-
message: expect.objectContaining({
147-
__sentry_template_string__: 'User %s logged in from %s',
148-
__sentry_template_values__: ['Alice', 'mobile'],
149-
}),
150-
});
173+
expect(mockCaptureLog).toHaveBeenCalledWith(
174+
{
175+
level: 'debug',
176+
message: expect.objectContaining({
177+
__sentry_template_string__: 'User %s logged in from %s',
178+
__sentry_template_values__: ['Alice', 'mobile'],
179+
}),
180+
},
181+
undefined,
182+
undefined,
183+
);
151184
});
185+
186+
it.each(['trace', 'debug', 'info', 'warn', 'error', 'fatal'] as const)(
187+
'should allow to pass a client and scope for %s level',
188+
level => {
189+
const client = new BrowserClient(getDefaultBrowserClientOptions());
190+
const scope = new sentryCore.Scope();
191+
192+
logger[level]('Test message', { key: 'value' }, client, scope);
193+
expect(mockCaptureLog).toHaveBeenCalledWith(
194+
{
195+
level,
196+
message: 'Test message',
197+
attributes: { key: 'value' },
198+
},
199+
client,
200+
scope,
201+
);
202+
},
203+
);
152204
});
Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
import { format } from 'node:util';
2-
import type { Log, LogSeverityLevel, ParameterizedString } from '@sentry/core';
2+
import type { Client, Log, LogSeverityLevel, ParameterizedString, Scope } from '@sentry/core';
33
import { _INTERNAL_captureLog } from '@sentry/core';
44

5-
export type CaptureLogArgs =
6-
| [message: ParameterizedString, attributes?: Log['attributes']]
7-
| [messageTemplate: string, messageParams: Array<unknown>, attributes?: Log['attributes']];
5+
type CaptureLogsArgsParametrized = [
6+
message: ParameterizedString,
7+
attributes?: Log['attributes'],
8+
client?: Client,
9+
scope?: Scope,
10+
];
11+
type CaptureLogsArgsTemplate = [
12+
messageTemplate: string,
13+
messageParams: Array<unknown>,
14+
attributes?: Log['attributes'],
15+
client?: Client,
16+
scope?: Scope,
17+
];
18+
19+
export type CaptureLogArgs = CaptureLogsArgsParametrized | CaptureLogsArgsTemplate;
820

921
/**
1022
* Capture a log with the given level.
@@ -14,16 +26,21 @@ export type CaptureLogArgs =
1426
* @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
1527
*/
1628
export function captureLog(level: LogSeverityLevel, ...args: CaptureLogArgs): void {
17-
const [messageOrMessageTemplate, paramsOrAttributes, maybeAttributes] = args;
18-
if (Array.isArray(paramsOrAttributes)) {
19-
const attributes = { ...maybeAttributes };
20-
attributes['sentry.message.template'] = messageOrMessageTemplate;
21-
paramsOrAttributes.forEach((param, index) => {
29+
if (!isParametrizedArgs(args)) {
30+
const [messageTemplate, messageParams, messageAttributes, client, scope] = args;
31+
const attributes = { ...messageAttributes };
32+
attributes['sentry.message.template'] = messageTemplate;
33+
messageParams.forEach((param, index) => {
2234
attributes[`sentry.message.parameter.${index}`] = param;
2335
});
24-
const message = format(messageOrMessageTemplate, ...paramsOrAttributes);
25-
_INTERNAL_captureLog({ level, message, attributes });
36+
const message = format(messageTemplate, ...messageParams);
37+
_INTERNAL_captureLog({ level, message, attributes }, client, scope);
2638
} else {
27-
_INTERNAL_captureLog({ level, message: messageOrMessageTemplate, attributes: paramsOrAttributes });
39+
const [message, attributes, client, scope] = args;
40+
_INTERNAL_captureLog({ level, message, attributes }, client, scope);
2841
}
2942
}
43+
44+
function isParametrizedArgs(args: CaptureLogArgs): args is CaptureLogsArgsParametrized {
45+
return !Array.isArray(args[1]);
46+
}

0 commit comments

Comments
 (0)