Skip to content

Commit 75aef10

Browse files
committed
feat: Show how to implement outside of client
1 parent d05e232 commit 75aef10

File tree

11 files changed

+582
-538
lines changed

11 files changed

+582
-538
lines changed

packages/browser/src/client.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
addAutoIpAddressToUser,
1616
applySdkMetadata,
1717
getSDKSource,
18+
_INTERNAL_flushLogsBuffer,
1819
} from '@sentry/core';
1920
import { eventFromException, eventFromMessage } from './eventbuilder';
2021
import { WINDOW } from './helpers';
@@ -91,7 +92,7 @@ export class BrowserClient extends Client<BrowserClientOptions> {
9192

9293
if (opts._experiments?.enableLogs) {
9394
setInterval(() => {
94-
this._flushLogsBuffer();
95+
_INTERNAL_flushLogsBuffer(this);
9596
}, 5000);
9697
}
9798

packages/core/src/client.ts

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,11 @@ import { parseSampleRate } from './utils/parseSampleRate';
6363
import { prepareEvent } from './utils/prepareEvent';
6464
import { showSpanDropWarning, spanToTraceContext } from './utils/spanUtils';
6565
import { convertSpanJsonToTransactionEvent, convertTransactionEventToSpanJson } from './utils/transactionEvent';
66-
import type { Log, SerializedOtelLog } from './types-hoist/log';
67-
import { SEVERITY_TEXT_TO_SEVERITY_NUMBER, createOtelLogEnvelope, logAttributeToSerializedLogAttribute } from './log';
66+
import type { SerializedOtelLog } from './types-hoist/log';
6867
import { _getSpanForScope } from './utils/spanOnScope';
6968

7069
const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
7170
const MISSING_RELEASE_FOR_SESSION_ERROR = 'Discarded session because of missing or non-string release';
72-
const MAX_LOG_BUFFER_SIZE = 100;
7371

7472
/**
7573
* Base implementation for all JavaScript SDK clients.
@@ -267,58 +265,6 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
267265
*/
268266
public captureCheckIn?(checkIn: CheckIn, monitorConfig?: MonitorConfig, scope?: Scope): string;
269267

270-
/**
271-
* Captures a log event and sends it to Sentry.
272-
*
273-
* @param log The log event to capture.
274-
*
275-
* @experimental This method will experience breaking changes. This is not yet part of
276-
* the stable Sentry SDK API and can be changed or removed without warning.
277-
*/
278-
public captureLog({ level, message, attributes, severityNumber }: Log, currentScope = getCurrentScope()): void {
279-
const { _experiments, release, environment } = this.getOptions();
280-
if (!_experiments?.enableLogs) {
281-
DEBUG_BUILD && logger.warn('logging option not enabled, log will not be captured.');
282-
return;
283-
}
284-
285-
const [, traceContext] = _getTraceInfoFromScope(this, currentScope);
286-
287-
const logAttributes = {
288-
...attributes,
289-
};
290-
291-
if (release) {
292-
logAttributes.release = release;
293-
}
294-
295-
if (environment) {
296-
logAttributes.environment = environment;
297-
}
298-
299-
const span = _getSpanForScope(currentScope);
300-
if (span) {
301-
// Add the parent span ID to the log attributes for trace context
302-
logAttributes['sentry.trace.parent_span_id'] = span.spanContext().spanId;
303-
}
304-
305-
const serializedLog: SerializedOtelLog = {
306-
severityText: level,
307-
body: {
308-
stringValue: message,
309-
},
310-
attributes: Object.entries(logAttributes).map(([key, value]) => logAttributeToSerializedLogAttribute(key, value)),
311-
timeUnixNano: `${new Date().getTime().toString()}000000`,
312-
traceId: traceContext?.trace_id,
313-
severityNumber: severityNumber ?? SEVERITY_TEXT_TO_SEVERITY_NUMBER[level],
314-
};
315-
316-
this._logsBuffer.push(serializedLog);
317-
if (this._logsBuffer.length > MAX_LOG_BUFFER_SIZE) {
318-
this._flushLogsBuffer();
319-
}
320-
}
321-
322268
/**
323269
* Get the current Dsn.
324270
*/
@@ -358,7 +304,6 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
358304
* still events in the queue when the timeout is reached.
359305
*/
360306
public flush(timeout?: number): PromiseLike<boolean> {
361-
this._flushLogsBuffer();
362307
const transport = this._transport;
363308
if (transport) {
364309
this.emit('flush');
@@ -1200,21 +1145,6 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
12001145
this.sendEnvelope(envelope);
12011146
}
12021147

1203-
/**
1204-
* Flushes the logs buffer to Sentry.
1205-
*/
1206-
protected _flushLogsBuffer(): void {
1207-
if (this._logsBuffer.length === 0) {
1208-
return;
1209-
}
1210-
1211-
const envelope = createOtelLogEnvelope(this._logsBuffer, this._options._metadata, this._options.tunnel, this._dsn);
1212-
this._logsBuffer = [];
1213-
// sendEnvelope should not throw
1214-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
1215-
this.sendEnvelope(envelope);
1216-
}
1217-
12181148
/**
12191149
* Creates an {@link Event} from all inputs to `captureException` and non-primitive inputs to `captureMessage`.
12201150
*/

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export { instrumentFetchRequest } from './fetch';
113113
export { trpcMiddleware } from './trpc';
114114
export { captureFeedback } from './feedback';
115115
export type { ReportDialogOptions } from './report-dialog';
116+
export { _INTERNAL_flushLogsBuffer } from './logs';
116117

117118
// TODO: Make this structure pretty again and don't do "export *"
118119
export * from './utils-hoist/index';

packages/core/src/log.ts

Lines changed: 0 additions & 91 deletions
This file was deleted.

packages/core/src/logs/constants.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { LogSeverityLevel } from '../types-hoist';
2+
3+
export const SEVERITY_TEXT_TO_SEVERITY_NUMBER: Partial<Record<LogSeverityLevel, number>> = {
4+
trace: 1,
5+
debug: 5,
6+
info: 9,
7+
warn: 13,
8+
error: 17,
9+
fatal: 21,
10+
};

packages/core/src/logs/envelope.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { createEnvelope } from '../utils-hoist';
2+
3+
import type { DsnComponents, SdkMetadata, SerializedOtelLog } from '../types-hoist';
4+
import type { OtelLogEnvelope, OtelLogItem } from '../types-hoist/envelope';
5+
import { dsnToString } from '../utils-hoist';
6+
7+
/**
8+
* Creates envelope item for a single log
9+
*/
10+
export function createOtelLogEnvelopeItem(log: SerializedOtelLog): OtelLogItem {
11+
const headers: OtelLogItem[0] = {
12+
type: 'otel_log',
13+
};
14+
15+
return [headers, log];
16+
}
17+
18+
/**
19+
* Records a log and sends it to sentry.
20+
*
21+
* Logs represent a message (and optionally some structured data) which provide context for a trace or error.
22+
* Ex: sentry.addLog({level: 'warning', message: `user ${user} just bought ${item}`, attributes: {user, item}}
23+
*
24+
* @params log - the log object which will be sent
25+
*/
26+
export function createOtelLogEnvelope(
27+
logs: Array<SerializedOtelLog>,
28+
metadata?: SdkMetadata,
29+
tunnel?: string,
30+
dsn?: DsnComponents,
31+
): OtelLogEnvelope {
32+
const headers: OtelLogEnvelope[0] = {};
33+
34+
if (metadata?.sdk) {
35+
headers.sdk = {
36+
name: metadata.sdk.name,
37+
version: metadata.sdk.version,
38+
};
39+
}
40+
41+
if (!!tunnel && !!dsn) {
42+
headers.dsn = dsnToString(dsn);
43+
}
44+
45+
return createEnvelope<OtelLogEnvelope>(headers, logs.map(createOtelLogEnvelopeItem));
46+
}

0 commit comments

Comments
 (0)