Skip to content

Commit f417ea6

Browse files
committed
feat(core): Add support for beforeSendLog
1 parent 2ed6fc2 commit f417ea6

File tree

4 files changed

+40
-6
lines changed

4 files changed

+40
-6
lines changed

packages/core/src/client.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -623,12 +623,19 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
623623
public on(hook: 'close', callback: () => void): () => void;
624624

625625
/**
626-
* A hook that is called before a log is captured
626+
* A hook that is called before a log is captured. This hooks runs before `beforeSendLog` is fired.
627627
*
628628
* @returns {() => void} A function that, when executed, removes the registered callback.
629629
*/
630630
public on(hook: 'beforeCaptureLog', callback: (log: Log) => void): () => void;
631631

632+
/**
633+
* A hook that is called after a log is captured
634+
*
635+
* @returns {() => void} A function that, when executed, removes the registered callback.
636+
*/
637+
public on(hook: 'afterCaptureLog', callback: (log: Log) => void): () => void;
638+
632639
/**
633640
* Register a hook on this client.
634641
*/
@@ -777,10 +784,15 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
777784
public emit(hook: 'close'): void;
778785

779786
/**
780-
* Emit a hook event for client before capturing a log
787+
* Emit a hook event for client before capturing a log. This hooks runs before `beforeSendLog` is fired.
781788
*/
782789
public emit(hook: 'beforeCaptureLog', log: Log): void;
783790

791+
/**
792+
* Emit a hook event for client after capturing a log.
793+
*/
794+
public emit(hook: 'afterCaptureLog', log: Log): void;
795+
784796
/**
785797
* Emit a hook that was previously registered via `on()`.
786798
*/

packages/core/src/logs/index.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,28 @@ export function logAttributeToSerializedLogAttribute(key: string, value: unknown
6262
* @experimental This method will experience breaking changes. This is not yet part of
6363
* the stable Sentry SDK API and can be changed or removed without warning.
6464
*/
65-
export function _INTERNAL_captureLog(log: Log, client = getClient(), scope = getCurrentScope()): void {
65+
export function _INTERNAL_captureLog(beforeLog: Log, client = getClient(), scope = getCurrentScope()): void {
6666
if (!client) {
6767
DEBUG_BUILD && logger.warn('No client available to capture log.');
6868
return;
6969
}
7070

7171
const { _experiments, release, environment } = client.getOptions();
72-
if (!_experiments?.enableLogs) {
72+
const { enableLogs = false, beforeSendLog } = _experiments ?? {};
73+
if (!enableLogs) {
7374
DEBUG_BUILD && logger.warn('logging option not enabled, log will not be captured.');
7475
return;
7576
}
7677

78+
client.emit('beforeCaptureLog', beforeLog);
79+
80+
const log = beforeSendLog ? beforeSendLog(beforeLog) : beforeLog;
81+
if (!log) {
82+
client.recordDroppedEvent('before_send', 'log_item', 1);
83+
DEBUG_BUILD && logger.warn('beforeSendLog returned null, log will not be captured.');
84+
return;
85+
}
86+
7787
const [, traceContext] = _getTraceInfoFromScope(client, scope);
7888

7989
const { level, message, attributes, severityNumber } = log;
@@ -117,7 +127,7 @@ export function _INTERNAL_captureLog(log: Log, client = getClient(), scope = get
117127
}
118128
}
119129

120-
client.emit('beforeCaptureLog', log);
130+
client.emit('afterCaptureLog', log);
121131
}
122132

123133
/**

packages/core/src/server-runtime-client.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class ServerRuntimeClient<
5757
_INTERNAL_flushLogsBuffer(client);
5858
});
5959

60-
this.on('beforeCaptureLog', log => {
60+
this.on('afterCaptureLog', log => {
6161
client._logWeight += estimateLogSizeInBytes(log);
6262

6363
// We flush the logs buffer if it exceeds 0.8 MB

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

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { CaptureContext } from '../scope';
22
import type { Breadcrumb, BreadcrumbHint } from './breadcrumb';
33
import type { ErrorEvent, EventHint, TransactionEvent } from './event';
44
import type { Integration } from './integration';
5+
import type { Log } from './log';
56
import type { TracesSamplerSamplingContext } from './samplingcontext';
67
import type { SdkMetadata } from './sdkmetadata';
78
import type { SpanJSON } from './span';
@@ -188,6 +189,17 @@ export interface ClientOptions<TO extends BaseTransportOptions = BaseTransportOp
188189
* If logs support should be enabled. Defaults to false.
189190
*/
190191
enableLogs?: boolean;
192+
/**
193+
* An event-processing callback for logs, guaranteed to be invoked after all other log
194+
* processors. This allows a log to be modified or dropped before it's sent.
195+
*
196+
* Note that you must return a valid log from this callback. If you do not wish to modify the log, simply return
197+
* it at the end. Returning `null` will cause the log to be dropped.
198+
*
199+
* @param log The log generated by the SDK.
200+
* @returns A new log that will be sent | null.
201+
*/
202+
beforeSendLog?: (log: Log) => Log | null;
191203
};
192204

193205
/**

0 commit comments

Comments
 (0)