import { LeveledLogEntry, LeveledLogEntryWithoutScope, LogEntry, LogEntryWithoutScope, Logger, LogLevel } from '.' /** * Default scope key for the Abstract Logger */ export const AbstractLoggerScope = '@sensenet/client-utils/AbstractLogger' /** * Abstract logger instance */ export abstract class AbstractLogger implements Logger { /** * Adds a new log entry to the logger * @param entry The Log entry object */ public abstract addEntry(entry: LeveledLogEntry, isVerbose?: boolean): Promise private async addEntryInternal(entry: LeveledLogEntry, isVerbose?: boolean) { try { await this.addEntry(entry, isVerbose) } catch (error) { this.error({ scope: AbstractLoggerScope, message: 'There was an error adding entry to the log', data: { entry, error, }, }) } } /** * Adds a Verbose level log entry. Verbose is the noisiest level, rarely (if ever) enabled for a production app. * @param entry The Log entry */ public async verbose(entry: LogEntry) { await this.addEntryInternal( { ...entry, level: LogLevel.Verbose, }, true, ) } /** * Adds a Debug level log entry. Debug is used for internal system events that are not necessarily observable from the outside, but useful when determining how something happened. * @param entry The Log entry */ public async debug(entry: LogEntry) { await this.addEntryInternal({ ...entry, level: LogLevel.Debug, }) } /** * Adds an Information level log entry. Information events describe things happening in the system that correspond to its responsibilities and functions. Generally these are the observable actions the system can perform. * @param entry The Log entry */ public async information(entry: LogEntry) { await this.addEntryInternal({ ...entry, level: LogLevel.Information, }) } /** * Adds a Warning level log entry. When service is degraded, endangered, or may be behaving outside of its expected parameters, Warning level events are used. * @param entry The Log entry */ public async warning(entry: LogEntry) { await this.addEntryInternal({ ...entry, level: LogLevel.Warning, }) } /** * Adds an Error level log entry. When functionality is unavailable or expectations broken, an Error event is used. * @param entry The Log entry */ public async error(entry: LogEntry) { try { await this.addEntry({ ...entry, level: LogLevel.Error, }) } catch (error) { await this.fatal({ scope: AbstractLoggerScope, message: 'There was an error persisting an Error event in the log and therefore the event was elevated to Fatal level.', data: { originalEntry: entry, error, }, }) } } /** * Adds a Fatal level log entry. The most critical level, Fatal events demand immediate attention. * @param entry The Log entry */ public async fatal(entry: LogEntry) { await this.addEntry({ ...entry, level: LogLevel.Fatal, }) } /** * Returns an object that contains shortcuts to the original logger that contains the provided scope. * usage example: * ```ts * const scopedLogger = myLogger.withScope("myLogScope") * scopedLogger.information({message: "foo"}) // will add an information entry with the provided scope * ``` */ public withScope = (scope: string) => ({ /** * Adds a custom log entry */ addEntry: (entry: LeveledLogEntryWithoutScope) => this.addEntry({ scope, ...entry }), /** * Adds a Verbose log entry. Verbose is the noisiest level, rarely (if ever) enabled for a production app. */ verbose: (entry: LogEntryWithoutScope) => this.verbose({ scope, ...entry }), /** * Adds a debug log entry. Debug is used for internal system events that are not necessarily observable from the outside, but useful when determining how something happened. */ debug: (entry: LogEntryWithoutScope) => this.debug({ scope, ...entry }), /** * Adds an Information log entry. Information events describe things happening in the system that correspond to its responsibilities and functions. Generally these are the observable actions the system can perform. */ information: (entry: LogEntryWithoutScope) => this.information({ scope, ...entry }), /** * Adds a Warning log entry. When service is degraded, endangered, or may be behaving outside of its expected parameters, Warning level events are used. */ warning: (entry: LogEntryWithoutScope) => this.warning({ scope, ...entry }), /** * Adds an Error log entry. When functionality is unavailable or expectations broken, an Error event is used. */ error: (entry: LogEntryWithoutScope) => this.error({ scope, ...entry }), /** * Adds a Fatal log entry. The most critical level, Fatal events demand immediate attention. */ fatal: (entry: LogEntryWithoutScope) => this.fatal({ scope, ...entry }), }) }