Skip to content

Commit 61feeb3

Browse files
authored
ref(core): Keep client-logger map on carrier & avoid side-effect (#16923)
Instead of having a side effect of writing on the GLOBAL_OBJ, we can use a global singleton instead. Part of #16846
1 parent 5c3175f commit 61feeb3

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

packages/core/src/carrier.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { AsyncContextStack } from './asyncContext/stackStrategy';
22
import type { AsyncContextStrategy } from './asyncContext/types';
3+
import type { Client } from './client';
34
import type { Scope } from './scope';
5+
import type { SerializedLog } from './types-hoist/log';
46
import type { Logger } from './utils/logger';
57
import { SDK_VERSION } from './utils/version';
68
import { GLOBAL_OBJ } from './utils/worldwide';
@@ -27,6 +29,11 @@ export interface SentryCarrier {
2729
/** @deprecated Logger is no longer set. Instead, we keep enabled state in loggerSettings. */
2830
logger?: Logger;
2931
loggerSettings?: { enabled: boolean };
32+
/**
33+
* A map of Sentry clients to their log buffers.
34+
* This is used to store logs that are sent to Sentry.
35+
*/
36+
clientToLogBufferMap?: WeakMap<Client, Array<SerializedLog>>;
3037

3138
/** Overwrites TextEncoder used in `@sentry/core`, need for `[email protected]` and older */
3239
encodePolyfill?: (input: string) => Uint8Array;

packages/core/src/logs/exports.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getGlobalSingleton } from '../carrier';
12
import type { Client } from '../client';
23
import { _getTraceInfoFromScope } from '../client';
34
import { getClient, getCurrentScope, getGlobalScope, getIsolationScope } from '../currentScopes';
@@ -9,15 +10,11 @@ import { isParameterizedString } from '../utils/is';
910
import { debug } from '../utils/logger';
1011
import { _getSpanForScope } from '../utils/spanOnScope';
1112
import { timestampInSeconds } from '../utils/time';
12-
import { GLOBAL_OBJ } from '../utils/worldwide';
1313
import { SEVERITY_TEXT_TO_SEVERITY_NUMBER } from './constants';
1414
import { createLogEnvelope } from './envelope';
1515

1616
const MAX_LOG_BUFFER_SIZE = 100;
1717

18-
// The reference to the Client <> LogBuffer map is stored to ensure it's always the same
19-
GLOBAL_OBJ._sentryClientToLogBufferMap = new WeakMap<Client, Array<SerializedLog>>();
20-
2118
/**
2219
* Converts a log attribute to a serialized log attribute.
2320
*
@@ -92,11 +89,13 @@ function setLogAttribute(
9289
* the stable Sentry SDK API and can be changed or removed without warning.
9390
*/
9491
export function _INTERNAL_captureSerializedLog(client: Client, serializedLog: SerializedLog): void {
92+
const bufferMap = _getBufferMap();
93+
9594
const logBuffer = _INTERNAL_getLogBuffer(client);
9695
if (logBuffer === undefined) {
97-
GLOBAL_OBJ._sentryClientToLogBufferMap?.set(client, [serializedLog]);
96+
bufferMap.set(client, [serializedLog]);
9897
} else {
99-
GLOBAL_OBJ._sentryClientToLogBufferMap?.set(client, [...logBuffer, serializedLog]);
98+
bufferMap.set(client, [...logBuffer, serializedLog]);
10099
if (logBuffer.length >= MAX_LOG_BUFFER_SIZE) {
101100
_INTERNAL_flushLogsBuffer(client, logBuffer);
102101
}
@@ -217,7 +216,7 @@ export function _INTERNAL_flushLogsBuffer(client: Client, maybeLogBuffer?: Array
217216
const envelope = createLogEnvelope(logBuffer, clientOptions._metadata, clientOptions.tunnel, client.getDsn());
218217

219218
// Clear the log buffer after envelopes have been constructed.
220-
GLOBAL_OBJ._sentryClientToLogBufferMap?.set(client, []);
219+
_getBufferMap().set(client, []);
221220

222221
client.emit('flushLogs');
223222

@@ -235,7 +234,7 @@ export function _INTERNAL_flushLogsBuffer(client: Client, maybeLogBuffer?: Array
235234
* @returns The log buffer for the given client.
236235
*/
237236
export function _INTERNAL_getLogBuffer(client: Client): Array<SerializedLog> | undefined {
238-
return GLOBAL_OBJ._sentryClientToLogBufferMap?.get(client);
237+
return _getBufferMap().get(client);
239238
}
240239

241240
/**
@@ -251,3 +250,8 @@ function getMergedScopeData(currentScope: Scope): ScopeData {
251250
mergeScopeData(scopeData, currentScope.getScopeData());
252251
return scopeData;
253252
}
253+
254+
function _getBufferMap(): WeakMap<Client, Array<SerializedLog>> {
255+
// The reference to the Client <> LogBuffer map is stored on the carrier to ensure it's always the same
256+
return getGlobalSingleton('clientToLogBufferMap', () => new WeakMap<Client, Array<SerializedLog>>());
257+
}

packages/core/src/utils/worldwide.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
/* eslint-disable @typescript-eslint/no-explicit-any */
1414

1515
import type { Carrier } from '../carrier';
16-
import type { Client } from '../client';
17-
import type { SerializedLog } from '../types-hoist/log';
1816
import type { Span } from '../types-hoist/span';
1917
import type { SdkSource } from './env';
2018

@@ -38,12 +36,6 @@ export type InternalGlobal = {
3836
id?: string;
3937
};
4038
SENTRY_SDK_SOURCE?: SdkSource;
41-
/**
42-
* A map of Sentry clients to their log buffers.
43-
*
44-
* This is used to store logs that are sent to Sentry.
45-
*/
46-
_sentryClientToLogBufferMap?: WeakMap<Client, Array<SerializedLog>>;
4739
/**
4840
* Debug IDs are indirectly injected by Sentry CLI or bundler plugins to directly reference a particular source map
4941
* for resolving of a source file. The injected code will place an entry into the record for each loaded bundle/JS

0 commit comments

Comments
 (0)