11import type { Client } from '../client' ;
22import { _getTraceInfoFromScope } from '../client' ;
3- import { getClient , getCurrentScope } from '../currentScopes' ;
3+ import { getClient , getCurrentScope , getGlobalScope , getIsolationScope } from '../currentScopes' ;
44import { DEBUG_BUILD } from '../debug-build' ;
5+ import type { Scope , ScopeData } from '../scope' ;
56import type { Log , SerializedLog , SerializedLogAttributeValue } from '../types-hoist/log' ;
7+ import { mergeScopeData } from '../utils/applyScopeDataToEvent' ;
68import { _getSpanForScope } from '../utils/spanOnScope' ;
79import { isParameterizedString } from '../utils-hoist/is' ;
810import { logger } from '../utils-hoist/logger' ;
@@ -61,6 +63,25 @@ export function logAttributeToSerializedLogAttribute(value: unknown): Serialized
6163 }
6264}
6365
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+
6485/**
6586 * Captures a serialized log event and adds it to the log buffer for the given client.
6687 *
@@ -96,7 +117,7 @@ export function _INTERNAL_captureSerializedLog(client: Client, serializedLog: Se
96117export function _INTERNAL_captureLog (
97118 beforeLog : Log ,
98119 client : Client | undefined = getClient ( ) ,
99- scope = getCurrentScope ( ) ,
120+ currentScope = getCurrentScope ( ) ,
100121 captureSerializedLog : ( client : Client , log : SerializedLog ) => void = _INTERNAL_captureSerializedLog ,
101122) : void {
102123 if ( ! client ) {
@@ -111,25 +132,27 @@ export function _INTERNAL_captureLog(
111132 return ;
112133 }
113134
114- const [ , traceContext ] = _getTraceInfoFromScope ( client , scope ) ;
135+ const [ , traceContext ] = _getTraceInfoFromScope ( client , currentScope ) ;
115136
116137 const processedLogAttributes = {
117138 ...beforeLog . attributes ,
118139 } ;
119140
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 ) ;
122148 }
123149
124- if ( environment ) {
125- processedLogAttributes [ 'sentry.environment' ] = environment ;
126- }
150+ setLogAttribute ( processedLogAttributes , 'sentry.release' , release ) ;
151+ setLogAttribute ( processedLogAttributes , 'sentry.environment' , environment ) ;
127152
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 ) ;
133156
134157 const beforeLogMessage = beforeLog . message ;
135158 if ( isParameterizedString ( beforeLogMessage ) ) {
@@ -140,11 +163,9 @@ export function _INTERNAL_captureLog(
140163 } ) ;
141164 }
142165
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 ) ;
148169
149170 const processedLog = { ...beforeLog , attributes : processedLogAttributes } ;
150171
@@ -218,3 +239,17 @@ export function _INTERNAL_flushLogsBuffer(client: Client, maybeLogBuffer?: Array
218239export function _INTERNAL_getLogBuffer ( client : Client ) : Array < SerializedLog > | undefined {
219240 return GLOBAL_OBJ . _sentryClientToLogBufferMap ?. get ( client ) ;
220241}
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