Skip to content

Commit a458fe7

Browse files
committed
wip
1 parent d27b99b commit a458fe7

File tree

5 files changed

+127
-99
lines changed

5 files changed

+127
-99
lines changed

packages/core/src/logs/internal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ export function _INTERNAL_captureLog(
160160
trace_id: traceContext?.trace_id,
161161
severity_number: severityNumber ?? SEVERITY_TEXT_TO_SEVERITY_NUMBER[level],
162162
attributes: {
163+
// TODO: This is too late to apply scope attributes because we already invoked beforeSendLog earlier.
163164
...scopeAttributes,
164165
...Object.keys(attributes).reduce((acc, key) => {
165166
acc[key] = attributeValueToTypedAttributeValue(attributes[key]);

packages/core/src/types-hoist/options.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,3 +518,22 @@ export interface CoreOptions<TO extends BaseTransportOptions = BaseTransportOpti
518518
*/
519519
stackParser?: StackParser | StackLineParser[];
520520
}
521+
522+
function myBeforeSendLog(log: Log) {
523+
log.attributes = {
524+
...log.attributes,
525+
myAttribute: 'myAttributeValue',
526+
};
527+
528+
if (log.attributes?.['myAttribute'] === 'something') {
529+
log.attributes['myAttribute'] = 'something else';
530+
}
531+
532+
log.attributes['otherAttribute'] = log.attributes['myAttribute'];
533+
534+
delete log.attributes['myAttribute'];
535+
536+
log.attributes['myAttribute'];
537+
538+
return log;
539+
}

packages/core/src/utils/applyScopeDataToEvent.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function mergeScopeData(data: ScopeData, mergeData: ScopeData): void {
3232
const {
3333
extra,
3434
tags,
35+
attributes,
3536
user,
3637
contexts,
3738
level,
@@ -47,6 +48,7 @@ export function mergeScopeData(data: ScopeData, mergeData: ScopeData): void {
4748

4849
mergeAndOverwriteScopeData(data, 'extra', extra);
4950
mergeAndOverwriteScopeData(data, 'tags', tags);
51+
mergeAndOverwriteScopeData(data, 'attributes', attributes);
5052
mergeAndOverwriteScopeData(data, 'user', user);
5153
mergeAndOverwriteScopeData(data, 'contexts', contexts);
5254

@@ -88,7 +90,7 @@ export function mergeScopeData(data: ScopeData, mergeData: ScopeData): void {
8890
* Exported only for tests.
8991
*/
9092
export function mergeAndOverwriteScopeData<
91-
Prop extends 'extra' | 'tags' | 'user' | 'contexts' | 'sdkProcessingMetadata',
93+
Prop extends 'extra' | 'tags' | 'attributes' | 'user' | 'contexts' | 'sdkProcessingMetadata',
9294
Data extends ScopeData,
9395
>(data: Data, prop: Prop, mergeVal: Data[Prop]): void {
9496
data[prop] = merge(data[prop], mergeVal, 1);

packages/core/test/lib/logs/internal.test.ts

Lines changed: 94 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,12 @@
11
import { describe, expect, it, vi } from 'vitest';
22
import { fmt, Scope } from '../../../src';
3-
import {
4-
_INTERNAL_captureLog,
5-
_INTERNAL_flushLogsBuffer,
6-
_INTERNAL_getLogBuffer,
7-
logAttributeToSerializedLogAttribute,
8-
} from '../../../src/logs/internal';
3+
import { _INTERNAL_captureLog, _INTERNAL_flushLogsBuffer, _INTERNAL_getLogBuffer } from '../../../src/logs/internal';
94
import type { Log } from '../../../src/types-hoist/log';
105
import * as loggerModule from '../../../src/utils/debug-logger';
116
import { getDefaultTestClientOptions, TestClient } from '../../mocks/client';
127

138
const PUBLIC_DSN = 'https://username@domain/123';
149

15-
describe('logAttributeToSerializedLogAttribute', () => {
16-
it('serializes integer values', () => {
17-
const result = logAttributeToSerializedLogAttribute(42);
18-
expect(result).toEqual({
19-
value: 42,
20-
type: 'integer',
21-
});
22-
});
23-
24-
it('serializes double values', () => {
25-
const result = logAttributeToSerializedLogAttribute(42.34);
26-
expect(result).toEqual({
27-
value: 42.34,
28-
type: 'double',
29-
});
30-
});
31-
32-
it('serializes boolean values', () => {
33-
const result = logAttributeToSerializedLogAttribute(true);
34-
expect(result).toEqual({
35-
value: true,
36-
type: 'boolean',
37-
});
38-
});
39-
40-
it('serializes string values', () => {
41-
const result = logAttributeToSerializedLogAttribute('username');
42-
expect(result).toEqual({
43-
value: 'username',
44-
type: 'string',
45-
});
46-
});
47-
48-
it('serializes object values as JSON strings', () => {
49-
const obj = { name: 'John', age: 30 };
50-
const result = logAttributeToSerializedLogAttribute(obj);
51-
expect(result).toEqual({
52-
value: JSON.stringify(obj),
53-
type: 'string',
54-
});
55-
});
56-
57-
it('serializes array values as JSON strings', () => {
58-
const array = [1, 2, 3, 'test'];
59-
const result = logAttributeToSerializedLogAttribute(array);
60-
expect(result).toEqual({
61-
value: JSON.stringify(array),
62-
type: 'string',
63-
});
64-
});
65-
66-
it('serializes undefined values as empty strings', () => {
67-
const result = logAttributeToSerializedLogAttribute(undefined);
68-
expect(result).toEqual({
69-
value: '',
70-
type: 'string',
71-
});
72-
});
73-
74-
it('serializes null values as JSON strings', () => {
75-
const result = logAttributeToSerializedLogAttribute(null);
76-
expect(result).toEqual({
77-
value: 'null',
78-
type: 'string',
79-
});
80-
});
81-
});
82-
8310
describe('_INTERNAL_captureLog', () => {
8411
it('captures and sends logs', () => {
8512
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableLogs: true });
@@ -215,31 +142,92 @@ describe('_INTERNAL_captureLog', () => {
215142
);
216143
});
217144

218-
it('includes custom attributes in log', () => {
219-
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableLogs: true });
220-
const client = new TestClient(options);
221-
const scope = new Scope();
222-
scope.setClient(client);
145+
describe('attributes', () => {
146+
it('includes custom attributes in log', () => {
147+
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableLogs: true });
148+
const client = new TestClient(options);
149+
const scope = new Scope();
150+
scope.setClient(client);
223151

224-
_INTERNAL_captureLog(
225-
{
226-
level: 'info',
227-
message: 'test log with custom attributes',
228-
attributes: { userId: '123', component: 'auth' },
229-
},
230-
scope,
231-
);
152+
_INTERNAL_captureLog(
153+
{
154+
level: 'info',
155+
message: 'test log with custom attributes',
156+
attributes: { userId: '123', component: 'auth' },
157+
},
158+
scope,
159+
);
232160

233-
const logAttributes = _INTERNAL_getLogBuffer(client)?.[0]?.attributes;
234-
expect(logAttributes).toEqual({
235-
userId: {
236-
value: '123',
237-
type: 'string',
238-
},
239-
component: {
240-
value: 'auth',
241-
type: 'string',
242-
},
161+
const logAttributes = _INTERNAL_getLogBuffer(client)?.[0]?.attributes;
162+
expect(logAttributes).toEqual({
163+
userId: {
164+
value: '123',
165+
type: 'string',
166+
},
167+
component: {
168+
value: 'auth',
169+
type: 'string',
170+
},
171+
});
172+
});
173+
174+
it('applies scope attributes attributes to log', () => {
175+
const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, enableLogs: true });
176+
const client = new TestClient(options);
177+
const scope = new Scope();
178+
scope.setClient(client);
179+
180+
scope.setAttribute('scope_1', 'attribute_value');
181+
scope.setAttribute('scope_2', { value: 143.5, type: 'double', unit: 'bytes' });
182+
scope.setAttributes({
183+
scope_3: true,
184+
scope_4: [1, 2, 3],
185+
scope_5: { value: [true, false, true], type: 'boolean[]', unit: 's' },
186+
});
187+
188+
_INTERNAL_captureLog(
189+
{
190+
level: 'info',
191+
message: 'test log with custom attributes',
192+
attributes: { userId: '123', component: 'auth' },
193+
},
194+
scope,
195+
);
196+
197+
const logAttributes = _INTERNAL_getLogBuffer(client)?.[0]?.attributes;
198+
199+
expect(logAttributes).toEqual({
200+
userId: {
201+
value: '123',
202+
type: 'string',
203+
},
204+
component: {
205+
value: 'auth',
206+
type: 'string',
207+
},
208+
scope_1: {
209+
type: 'string',
210+
value: 'attribute_value',
211+
},
212+
scope_2: {
213+
type: 'double',
214+
unit: 'bytes',
215+
value: 143.5,
216+
},
217+
scope_3: {
218+
type: 'boolean',
219+
value: true,
220+
},
221+
scope_4: {
222+
type: 'integer[]',
223+
value: [1, 2, 3],
224+
},
225+
scope_5: {
226+
type: 'boolean[]',
227+
value: [true, false, true],
228+
unit: 's',
229+
},
230+
});
243231
});
244232
});
245233

@@ -326,6 +314,9 @@ describe('_INTERNAL_captureLog', () => {
326314
const scope = new Scope();
327315
scope.setClient(client);
328316

317+
scope.setAttribute('scope_1', 'attribute_value');
318+
scope.setAttribute('scope_2', { value: 143.5, type: 'double', unit: 'bytes' });
319+
329320
_INTERNAL_captureLog(
330321
{
331322
level: 'info',
@@ -338,7 +329,12 @@ describe('_INTERNAL_captureLog', () => {
338329
expect(beforeSendLog).toHaveBeenCalledWith({
339330
level: 'info',
340331
message: 'original message',
341-
attributes: { original: true },
332+
attributes: {
333+
original: true,
334+
// scope attributes should already be applied prior to beforeSendLog
335+
scope_1: 'attribute_value',
336+
scope_2: { value: 143.5, type: 'double', unit: 'bytes' },
337+
},
342338
});
343339

344340
const logBuffer = _INTERNAL_getLogBuffer(client);

packages/core/test/lib/utils/applyScopeDataToEvent.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ describe('mergeScopeData', () => {
8383
breadcrumbs: [],
8484
user: {},
8585
tags: {},
86+
attributes: {},
8687
extra: {},
8788
contexts: {},
8889
attachments: [],
@@ -95,6 +96,7 @@ describe('mergeScopeData', () => {
9596
breadcrumbs: [],
9697
user: {},
9798
tags: {},
99+
attributes: {},
98100
extra: {},
99101
contexts: {},
100102
attachments: [],
@@ -108,6 +110,7 @@ describe('mergeScopeData', () => {
108110
breadcrumbs: [],
109111
user: {},
110112
tags: {},
113+
attributes: {},
111114
extra: {},
112115
contexts: {},
113116
attachments: [],
@@ -135,6 +138,7 @@ describe('mergeScopeData', () => {
135138
breadcrumbs: [breadcrumb1],
136139
user: { id: '1', email: 'test@example.com' },
137140
tags: { tag1: 'aa', tag2: 'aa' },
141+
attributes: { attr1: { value: 'value1', type: 'string' }, attr2: { value: 123, type: 'integer' } },
138142
extra: { extra1: 'aa', extra2: 'aa' },
139143
contexts: { os: { name: 'os1' }, culture: { display_name: 'name1' } },
140144
attachments: [attachment1],
@@ -155,6 +159,7 @@ describe('mergeScopeData', () => {
155159
breadcrumbs: [breadcrumb2, breadcrumb3],
156160
user: { id: '2', name: 'foo' },
157161
tags: { tag2: 'bb', tag3: 'bb' },
162+
attributes: { attr2: { value: 456, type: 'integer' }, attr3: { value: 'value3', type: 'string' } },
158163
extra: { extra2: 'bb', extra3: 'bb' },
159164
contexts: { os: { name: 'os2' } },
160165
attachments: [attachment2, attachment3],
@@ -176,6 +181,11 @@ describe('mergeScopeData', () => {
176181
breadcrumbs: [breadcrumb1, breadcrumb2, breadcrumb3],
177182
user: { id: '2', name: 'foo', email: 'test@example.com' },
178183
tags: { tag1: 'aa', tag2: 'bb', tag3: 'bb' },
184+
attributes: {
185+
attr1: { value: 'value1', type: 'string' },
186+
attr2: { value: 456, type: 'integer' },
187+
attr3: { value: 'value3', type: 'string' },
188+
},
179189
extra: { extra1: 'aa', extra2: 'bb', extra3: 'bb' },
180190
contexts: { os: { name: 'os2' }, culture: { display_name: 'name1' } },
181191
attachments: [attachment1, attachment2, attachment3],

0 commit comments

Comments
 (0)