feat(logger): add explicit Sentry event channel
This commit is contained in:
+18
-2
@@ -97,13 +97,20 @@ export function createLogger(options: LoggerOptions): Logger {
|
||||
levelRank(level) >= levelRank(threshold) &&
|
||||
(!runtimeOverride?.namespaces.length ||
|
||||
namespaceMatches(namespace, runtimeOverride.namespaces));
|
||||
const emit = (level: Exclude<LogLevel, "silent">, arguments_: readonly unknown[]) => {
|
||||
if (!enabled(level)) return;
|
||||
const emit = (
|
||||
level: Exclude<LogLevel, "silent">,
|
||||
arguments_: readonly unknown[],
|
||||
sendToSentry = false,
|
||||
) => {
|
||||
const sendToConsole = enabled(level);
|
||||
if (!sendToConsole && !sendToSentry) return;
|
||||
const event: LogEvent = {
|
||||
level,
|
||||
namespace,
|
||||
arguments: evaluate(arguments_),
|
||||
timestamp: new Date(),
|
||||
sendToSentry,
|
||||
sendToConsole,
|
||||
};
|
||||
sinks.forEach((sink) => sink.emit(event));
|
||||
};
|
||||
@@ -123,6 +130,14 @@ export function createLogger(options: LoggerOptions): Logger {
|
||||
};
|
||||
const api: Logger = {
|
||||
namespace,
|
||||
sentry: {
|
||||
trace: (...items) => emit("trace", items, true),
|
||||
debug: (...items) => emit("debug", items, true),
|
||||
log: (...items) => emit("info", items, true),
|
||||
info: (...items) => emit("info", items, true),
|
||||
warn: (...items) => emit("warn", items, true),
|
||||
error: (...items) => emit("error", items, true),
|
||||
},
|
||||
child: (child) =>
|
||||
createLogger({ ...options, namespace: [namespace, child].filter(Boolean) as string[] }),
|
||||
trace: (...items) => emit("trace", items),
|
||||
@@ -187,6 +202,7 @@ function supportsAnsi(): boolean {
|
||||
export function createConsoleSink(): LogSink {
|
||||
return {
|
||||
emit: (event) => {
|
||||
if (!event.sendToConsole) return;
|
||||
const method = event.level === "trace" ? "debug" : event.level;
|
||||
const console_ = globalThis.console as Console & Record<string, unknown>;
|
||||
const fn = console_[method];
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@ export interface SentryLike {
|
||||
export function createSentrySink(sentry: SentryLike): LogSink {
|
||||
return {
|
||||
emit(event: LogEvent) {
|
||||
if (event.level !== "error") return;
|
||||
if (event.level !== "error" && !event.sendToSentry) return;
|
||||
const error = event.arguments.find((item): item is Error => item instanceof Error);
|
||||
const extras = Object.fromEntries(
|
||||
event.arguments
|
||||
@@ -26,11 +26,11 @@ export function createSentrySink(sentry: SentryLike): LogSink {
|
||||
event.arguments.filter((item) => typeof item === "string").join(" ") ||
|
||||
"Logger error";
|
||||
sentry.withScope((scope) => {
|
||||
scope.setLevel("error");
|
||||
scope.setLevel(event.level);
|
||||
if (event.namespace) scope.setTag("logger.namespace", event.namespace);
|
||||
scope.setExtras(extras);
|
||||
if (error) sentry.captureException(error);
|
||||
else sentry.captureMessage(message, "error");
|
||||
else sentry.captureMessage(message, event.level);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -9,6 +9,10 @@ export interface LogEvent {
|
||||
namespace?: string;
|
||||
arguments: readonly unknown[];
|
||||
timestamp: Date;
|
||||
/** Whether this event was explicitly selected for Sentry capture. */
|
||||
sendToSentry: boolean;
|
||||
/** Whether the default console sink should render this event. */
|
||||
sendToConsole: boolean;
|
||||
}
|
||||
|
||||
/** A destination for enabled log events. */
|
||||
@@ -33,8 +37,20 @@ export interface LoggerOptions {
|
||||
sinks?: readonly LogSink[];
|
||||
}
|
||||
|
||||
/** Explicit Sentry reporting methods. These bypass the logger's normal level threshold. */
|
||||
export interface SentryLogger {
|
||||
trace(...arguments_: readonly unknown[]): void;
|
||||
debug(...arguments_: readonly unknown[]): void;
|
||||
log(...arguments_: readonly unknown[]): void;
|
||||
info(...arguments_: readonly unknown[]): void;
|
||||
warn(...arguments_: readonly unknown[]): void;
|
||||
error(...arguments_: readonly unknown[]): void;
|
||||
}
|
||||
|
||||
export interface Logger {
|
||||
readonly namespace?: string;
|
||||
/** Sends selected events to a configured Sentry sink without changing the default policy for other logs. */
|
||||
readonly sentry: SentryLogger;
|
||||
child(namespace: string): Logger;
|
||||
trace(...arguments_: readonly unknown[]): void;
|
||||
debug(...arguments_: readonly unknown[]): void;
|
||||
|
||||
Reference in New Issue
Block a user