diff --git a/src/constants.ts b/src/constants.ts index 2a5e6c0..1d9821e 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -16,8 +16,11 @@ export enum LogLevel { TRACE = 'trace', DEBUG = 'debug', + FATAL = 'fatal', INFO = 'info', + LOG = 'log', WARN = 'warn', + WARNING = 'warning', ERROR = 'error', SILENT = 'silent', } diff --git a/src/sinks/console.ts b/src/sinks/console.ts index 32121ce..2266111 100644 --- a/src/sinks/console.ts +++ b/src/sinks/console.ts @@ -1,14 +1,18 @@ -import type { LogLevel, LogSink } from '../types'; +import { LogLevel } from '../constants'; +import type { LogSink } from '../types'; + +type ConsoleLogLevel = + `${Exclude}`; const ANSI_RESET = '\u001B[0m'; -const ANSI_BY_LEVEL: Record, string> = { +const ANSI_BY_LEVEL: Record = { trace: '\u001B[90m', debug: '\u001B[36m', info: '\u001B[32m', warn: '\u001B[33m', error: '\u001B[31m', }; -const BROWSER_STYLE_BY_LEVEL: Record, string> = { +const BROWSER_STYLE_BY_LEVEL: Record = { trace: 'color: #6b7280; font-weight: 600', debug: 'color: #0891b2; font-weight: 600', info: 'color: #15803d; font-weight: 600', @@ -51,7 +55,7 @@ function supportsAnsi(): boolean { export function createConsoleSink(): LogSink { return { emit: (event) => { - if (!event.sendToConsole) return; + if (!event.sendToConsole || event.level === LogLevel.SILENT) return; const method = event.level === 'trace' ? 'debug' : event.level; const console_ = globalThis.console as Console & Record; const fn = console_[method]; diff --git a/src/sinks/sentry.ts b/src/sinks/sentry.ts index 966c6fc..3ffe007 100644 --- a/src/sinks/sentry.ts +++ b/src/sinks/sentry.ts @@ -1,10 +1,12 @@ -import type { LogEvent, LogLevel, LogSink } from '../types'; +import type { LogEvent, LogSink } from '../types'; +import { LogLevel } from '../constants'; /** * Sentry Issue severity levels (`@sentry/core` `SeverityLevel`). * Note: Issues use `"warning"`; Logs use `"warn"`. */ -export type SentrySeverityLevel = 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug'; +export type SentrySeverityLevel = + `${Exclude}`; /** * Options for {@link createSentrySink}. @@ -23,7 +25,7 @@ export interface SentrySinkOptions { * Minimum level for automatic Sentry Logs delivery when {@link SentrySinkOptions.logs} * is enabled. Per-call `{ sentry: true }` bypasses this threshold. */ - logLevel?: LogLevel; + logLevel?: Exclude; } /** @@ -124,9 +126,11 @@ export function isSentrySink(sink: LogSink): sink is SentrySink { * * @param level - Logger emit level (never `silent`). */ -export function toSentrySeverity(level: Exclude): SentrySeverityLevel { - if (level === 'warn') return 'warning'; - if (level === 'trace') return 'debug'; +export function toSentrySeverity( + level: `${Exclude}`, +): SentrySeverityLevel { + if (level === LogLevel.WARN) return LogLevel.WARNING; + if (level === LogLevel.TRACE) return LogLevel.DEBUG; return level; } @@ -202,6 +206,7 @@ export function createSentrySink(sentry: SentryLike, options: SentrySinkOptions options, emit(event: LogEvent) { if (event.environment === 'development') return; + if (event.level === LogLevel.SILENT) return; if (event.sendToSentryIssue) { const error = event.arguments.find((item): item is Error => item instanceof Error); const { message, attributes } = toSentryLogPayload(event); @@ -217,7 +222,7 @@ export function createSentrySink(sentry: SentryLike, options: SentrySinkOptions } if (!event.sendToSentryLogs || !sentry.logger) return; const method = event.level === 'trace' ? 'trace' : event.level; - const log = sentry.logger[method]; + const log = sentry.logger[method as keyof SentryLoggerApiLike]; if (typeof log !== 'function') return; const { message, attributes } = toSentryLogPayload(event); log.call(sentry.logger, message, attributes); diff --git a/src/types.ts b/src/types.ts index b128ced..d7d4935 100644 --- a/src/types.ts +++ b/src/types.ts @@ -15,7 +15,8 @@ import { LogLevel as LogLevelEnum, LoggerEnvironment as LoggerEnvironmentEnum } * A logger emits events at or above its configured threshold (e.g. `warn` * allows `warn` and `error`). */ -export type LogLevel = `${LogLevelEnum}`; +export type LogLevel = + `${Exclude}`; /** * Deployment stage used to pick a default log level when none is configured @@ -70,7 +71,7 @@ export interface LogCallOptions { */ export interface LogEvent { /** Severity of this event. Never `silent`. */ - level: Exclude; + level: Exclude; /** * Colon-joined namespace for this logger (e.g. `"WIDGET:Button"`). * Omitted when the logger was created without a namespace.