Skip to content

Commit e21944b

Browse files
committed
unify attributeValueToTypedAttributeValue with optional fallback logic
1 parent ab276bd commit e21944b

File tree

4 files changed

+32
-33
lines changed

4 files changed

+32
-33
lines changed

packages/core/src/attributes.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,47 @@ export function isAttributeObject(maybeObj: unknown): maybeObj is AttributeObjec
6161
);
6262
}
6363

64+
export function attributeValueToTypedAttributeValue(rawValue: unknown, useFallback?: true): TypedAttributeValue;
6465
/**
6566
* Converts an attribute value to a typed attribute value.
6667
*
6768
* Does not allow mixed arrays. In case of a mixed array, the value is stringified and the type is 'string'.
6869
* All values besides the supported attribute types (see {@link AttributeTypeMap}) are stringified to a string attribute value.
6970
*
7071
* @param value - The value of the passed attribute.
72+
* @param useFallback - If true, unsupported values will be stringified to a string attribute value.
73+
* Defaults to false. In this case, `undefined` is returned for unsupported values.
7174
* @returns The typed attribute.
7275
*/
73-
export function attributeValueToTypedAttributeValue(rawValue: unknown): TypedAttributeValue | void {
76+
export function attributeValueToTypedAttributeValue(
77+
rawValue: unknown,
78+
useFallback = false,
79+
): TypedAttributeValue | void {
7480
const { value, unit } = isAttributeObject(rawValue) ? rawValue : { value: rawValue, unit: undefined };
7581
const attributeValue = getTypedAttributeValue(value);
82+
const checkedUnit = unit && typeof unit === 'string' ? { unit } : {};
7683
if (attributeValue) {
77-
return { ...attributeValue, ...(unit && typeof unit === 'string' ? { unit } : {}) };
84+
return { ...attributeValue, ...checkedUnit };
7885
}
86+
87+
if (!useFallback) {
88+
return;
89+
}
90+
91+
// Fallback: stringify the value
92+
// TODO(v11): be smarter here and use String constructor if stringify fails
93+
// (this is a breaking change for already existing attribute values)
94+
let stringValue = '';
95+
try {
96+
stringValue = JSON.stringify(value) ?? '';
97+
} catch {
98+
// Do nothing
99+
}
100+
return {
101+
value: stringValue,
102+
type: 'string',
103+
...checkedUnit,
104+
};
79105
}
80106

81107
/**

packages/core/src/logs/internal.ts

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,6 @@ import { createLogEnvelope } from './envelope';
1717

1818
const MAX_LOG_BUFFER_SIZE = 100;
1919

20-
/**
21-
* Converts a log attribute to a serialized log attribute.
22-
*
23-
* @param key - The key of the log attribute.
24-
* @param value - The value of the log attribute.
25-
* @returns The serialized log attribute.
26-
*/
27-
export function attributeValueToTypedAttributeValueWithFallback(value: unknown): TypedAttributeValue {
28-
const typedAttributeValue = attributeValueToTypedAttributeValue(value);
29-
if (typedAttributeValue) {
30-
return typedAttributeValue;
31-
}
32-
33-
let stringValue = '';
34-
try {
35-
stringValue = JSON.stringify(value) ?? '';
36-
} catch {
37-
// Do nothing
38-
}
39-
return {
40-
value: stringValue,
41-
type: 'string',
42-
};
43-
}
44-
4520
/**
4621
* Sets a log attribute if the value exists and the attribute key is not already present.
4722
*
@@ -198,7 +173,7 @@ export function _INTERNAL_captureLog(
198173
),
199174
...Object.keys(logAttributes).reduce(
200175
(acc, key) => {
201-
acc[key] = attributeValueToTypedAttributeValueWithFallback(logAttributes[key]);
176+
acc[key] = attributeValueToTypedAttributeValue(logAttributes[key], true);
202177
return acc;
203178
},
204179
{} as Record<string, TypedAttributeValue>,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { TypedAttributes } from '../attributes';
1+
import type { Attributes } from '../attributes';
22
import type { ParameterizedString } from './parameterize';
33

44
export type LogSeverityLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
@@ -55,7 +55,7 @@ export interface SerializedLog {
5555
/**
5656
* Arbitrary structured data that stores information about the log - e.g., userId: 100.
5757
*/
58-
attributes?: TypedAttributes;
58+
attributes?: Attributes;
5959

6060
/**
6161
* The severity number.

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,7 @@ describe('_INTERNAL_captureLog', () => {
326326
message: 'original message',
327327
attributes: {
328328
original: true,
329-
// attributes here still have the same form as originally set on the scope or log
330-
scope_1: 'attribute_value',
331-
scope_2: { value: 38, unit: 'gigabytes' },
329+
// scope attributes are not included in beforeSendLog - they're only added during serialization
332330
},
333331
});
334332

0 commit comments

Comments
 (0)