1
1
import type { Client } from '../client' ;
2
2
import { _getTraceInfoFromScope } from '../client' ;
3
- import { getClient , getCurrentScope } from '../currentScopes' ;
3
+ import { getClient , getCurrentScope , getGlobalScope , getIsolationScope } from '../currentScopes' ;
4
4
import { DEBUG_BUILD } from '../debug-build' ;
5
+ import type { Scope , ScopeData } from '../scope' ;
5
6
import type { Log , SerializedLog , SerializedLogAttributeValue } from '../types-hoist/log' ;
7
+ import { mergeScopeData } from '../utils/applyScopeDataToEvent' ;
6
8
import { _getSpanForScope } from '../utils/spanOnScope' ;
7
9
import { isParameterizedString } from '../utils-hoist/is' ;
8
10
import { logger } from '../utils-hoist/logger' ;
@@ -61,6 +63,25 @@ export function logAttributeToSerializedLogAttribute(value: unknown): Serialized
61
63
}
62
64
}
63
65
66
+ /**
67
+ * Sets a log attribute if the value exists and the attribute key is not already present.
68
+ *
69
+ * @param logAttributes - The log attributes object to modify.
70
+ * @param key - The attribute key to set.
71
+ * @param value - The value to set (only sets if truthy and key not present).
72
+ * @param setEvenIfPresent - Whether to set the attribute if it is present. Defaults to true.
73
+ */
74
+ function setLogAttribute (
75
+ logAttributes : Record < string , unknown > ,
76
+ key : string ,
77
+ value : unknown ,
78
+ setEvenIfPresent = true ,
79
+ ) : void {
80
+ if ( value && ( ! logAttributes [ key ] || setEvenIfPresent ) ) {
81
+ logAttributes [ key ] = value ;
82
+ }
83
+ }
84
+
64
85
/**
65
86
* Captures a serialized log event and adds it to the log buffer for the given client.
66
87
*
@@ -96,7 +117,7 @@ export function _INTERNAL_captureSerializedLog(client: Client, serializedLog: Se
96
117
export function _INTERNAL_captureLog (
97
118
beforeLog : Log ,
98
119
client : Client | undefined = getClient ( ) ,
99
- scope = getCurrentScope ( ) ,
120
+ currentScope = getCurrentScope ( ) ,
100
121
captureSerializedLog : ( client : Client , log : SerializedLog ) => void = _INTERNAL_captureSerializedLog ,
101
122
) : void {
102
123
if ( ! client ) {
@@ -111,25 +132,27 @@ export function _INTERNAL_captureLog(
111
132
return ;
112
133
}
113
134
114
- const [ , traceContext ] = _getTraceInfoFromScope ( client , scope ) ;
135
+ const [ , traceContext ] = _getTraceInfoFromScope ( client , currentScope ) ;
115
136
116
137
const processedLogAttributes = {
117
138
...beforeLog . attributes ,
118
139
} ;
119
140
120
- if ( release ) {
121
- processedLogAttributes [ 'sentry.release' ] = release ;
141
+ const { user } = getMergedScopeData ( currentScope ) ;
142
+ // Only attach user to log attributes if sendDefaultPii is enabled
143
+ if ( client . getOptions ( ) . sendDefaultPii ) {
144
+ const { id, email, username } = user ;
145
+ setLogAttribute ( processedLogAttributes , 'user.id' , id , false ) ;
146
+ setLogAttribute ( processedLogAttributes , 'user.email' , email , false ) ;
147
+ setLogAttribute ( processedLogAttributes , 'user.name' , username , false ) ;
122
148
}
123
149
124
- if ( environment ) {
125
- processedLogAttributes [ 'sentry.environment' ] = environment ;
126
- }
150
+ setLogAttribute ( processedLogAttributes , 'sentry.release' , release ) ;
151
+ setLogAttribute ( processedLogAttributes , 'sentry.environment' , environment ) ;
127
152
128
- const { sdk } = client . getSdkMetadata ( ) ?? { } ;
129
- if ( sdk ) {
130
- processedLogAttributes [ 'sentry.sdk.name' ] = sdk . name ;
131
- processedLogAttributes [ 'sentry.sdk.version' ] = sdk . version ;
132
- }
153
+ const { name, version } = client . getSdkMetadata ( ) ?. sdk ?? { } ;
154
+ setLogAttribute ( processedLogAttributes , 'sentry.sdk.name' , name ) ;
155
+ setLogAttribute ( processedLogAttributes , 'sentry.sdk.version' , version ) ;
133
156
134
157
const beforeLogMessage = beforeLog . message ;
135
158
if ( isParameterizedString ( beforeLogMessage ) ) {
@@ -140,11 +163,9 @@ export function _INTERNAL_captureLog(
140
163
} ) ;
141
164
}
142
165
143
- const span = _getSpanForScope ( scope ) ;
144
- if ( span ) {
145
- // Add the parent span ID to the log attributes for trace context
146
- processedLogAttributes [ 'sentry.trace.parent_span_id' ] = span . spanContext ( ) . spanId ;
147
- }
166
+ const span = _getSpanForScope ( currentScope ) ;
167
+ // Add the parent span ID to the log attributes for trace context
168
+ setLogAttribute ( processedLogAttributes , 'sentry.trace.parent_span_id' , span ?. spanContext ( ) . spanId ) ;
148
169
149
170
const processedLog = { ...beforeLog , attributes : processedLogAttributes } ;
150
171
@@ -218,3 +239,17 @@ export function _INTERNAL_flushLogsBuffer(client: Client, maybeLogBuffer?: Array
218
239
export function _INTERNAL_getLogBuffer ( client : Client ) : Array < SerializedLog > | undefined {
219
240
return GLOBAL_OBJ . _sentryClientToLogBufferMap ?. get ( client ) ;
220
241
}
242
+
243
+ /**
244
+ * Get the scope data for the current scope after merging with the
245
+ * global scope and isolation scope.
246
+ *
247
+ * @param currentScope - The current scope.
248
+ * @returns The scope data.
249
+ */
250
+ function getMergedScopeData ( currentScope : Scope ) : ScopeData {
251
+ const scopeData = getGlobalScope ( ) . getScopeData ( ) ;
252
+ mergeScopeData ( scopeData , getIsolationScope ( ) . getScopeData ( ) ) ;
253
+ mergeScopeData ( scopeData , currentScope . getScopeData ( ) ) ;
254
+ return scopeData ;
255
+ }
0 commit comments