UNPKG

loglayer

Version:

A modern logging library with a fluent API for specifying log messages, metadata and errors

1,264 lines (1,209 loc) 36.8 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;// src/index.ts var _plugin = require('@loglayer/plugin'); var _shared = require('@loglayer/shared'); // src/LogLayer.ts var _contextmanager = require('@loglayer/context-manager'); // src/LogBuilder.ts var LogBuilder = class { constructor(structuredLogger) { this.err = null; this.metadata = {}; this.structuredLogger = structuredLogger; this.hasMetadata = false; this.pluginManager = structuredLogger["pluginManager"]; } /** * Specifies metadata to include with the log message * * @see {@link https://loglayer.dev/logging-api/metadata.html | Metadata Docs} */ withMetadata(metadata) { const { pluginManager, structuredLogger: { _config: { consoleDebug } } } = this; if (!metadata) { if (consoleDebug) { console.debug("[LogLayer] withMetadata was called with no metadata; dropping."); } return this; } let data = metadata; if (pluginManager.hasPlugins(_plugin.PluginCallbackType.onMetadataCalled)) { data = pluginManager.runOnMetadataCalled(metadata, this.structuredLogger); if (!data) { if (consoleDebug) { console.debug("[LogLayer] Metadata was dropped due to plugin returning falsy value."); } return this; } } this.metadata = { ...this.metadata, ...data }; this.hasMetadata = true; return this; } /** * Specifies an Error to include with the log message * * @see {@link https://loglayer.dev/logging-api/error-handling.html | Error Handling Docs} */ withError(error) { this.err = error; return this; } /** * Sends a log message to the logging library under an info log level. */ info(...messages) { if (!this.structuredLogger.isLevelEnabled(_shared.LogLevel.info)) return; this.structuredLogger._formatMessage(messages); this.formatLog(_shared.LogLevel.info, messages); } /** * Sends a log message to the logging library under the warn log level */ warn(...messages) { if (!this.structuredLogger.isLevelEnabled(_shared.LogLevel.warn)) return; this.structuredLogger._formatMessage(messages); this.formatLog(_shared.LogLevel.warn, messages); } /** * Sends a log message to the logging library under the error log level */ error(...messages) { if (!this.structuredLogger.isLevelEnabled(_shared.LogLevel.error)) return; this.structuredLogger._formatMessage(messages); this.formatLog(_shared.LogLevel.error, messages); } /** * Sends a log message to the logging library under the debug log level * * The logging library may or may not support multiple message parameters and only * the first parameter would be used. */ debug(...messages) { if (!this.structuredLogger.isLevelEnabled(_shared.LogLevel.debug)) return; this.structuredLogger._formatMessage(messages); this.formatLog(_shared.LogLevel.debug, messages); } /** * Sends a log message to the logging library under the trace log level * * The logging library may or may not support multiple message parameters and only * the first parameter would be used. */ trace(...messages) { if (!this.structuredLogger.isLevelEnabled(_shared.LogLevel.trace)) return; this.structuredLogger._formatMessage(messages); this.formatLog(_shared.LogLevel.trace, messages); } /** * Sends a log message to the logging library under the fatal log level * * The logging library may or may not support multiple message parameters and only * the first parameter would be used. */ fatal(...messages) { if (!this.structuredLogger.isLevelEnabled(_shared.LogLevel.fatal)) return; this.structuredLogger._formatMessage(messages); this.formatLog(_shared.LogLevel.fatal, messages); } /** * All logging inputs are dropped and stops sending logs to the logging library. */ disableLogging() { this.structuredLogger.disableLogging(); return this; } /** * Enable sending logs to the logging library. */ enableLogging() { this.structuredLogger.enableLogging(); return this; } formatLog(logLevel, params) { const { muteMetadata } = this.structuredLogger._config; const hasData = muteMetadata ? false : this.hasMetadata; this.structuredLogger._formatLog({ logLevel, params, metadata: hasData ? this.metadata : null, err: this.err }); } }; // src/PluginManager.ts var CALLBACK_LIST = [ _plugin.PluginCallbackType.onBeforeDataOut, _plugin.PluginCallbackType.onMetadataCalled, _plugin.PluginCallbackType.shouldSendToLogger, _plugin.PluginCallbackType.onBeforeMessageOut, _plugin.PluginCallbackType.onContextCalled ]; var PluginManager = (_class = class { // Indexes for each plugin type __init() {this.onBeforeDataOut = []} __init2() {this.shouldSendToLogger = []} __init3() {this.onMetadataCalled = []} __init4() {this.onBeforeMessageOut = []} __init5() {this.onContextCalled = []} constructor(plugins) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this); this.idToPlugin = {}; this.mapPlugins(plugins); this.indexPlugins(); } mapPlugins(plugins) { for (const plugin of plugins) { if (!plugin.id) { plugin.id = Date.now().toString() + Math.random().toString(); } if (this.idToPlugin[plugin.id]) { throw new Error(`[LogLayer] Plugin with id ${plugin.id} already exists.`); } plugin["registeredAt"] = Date.now(); this.idToPlugin[plugin.id] = plugin; } } indexPlugins() { this.onBeforeDataOut = []; this.shouldSendToLogger = []; this.onMetadataCalled = []; this.onBeforeMessageOut = []; this.onContextCalled = []; const pluginList = Object.values(this.idToPlugin).sort((a, b) => a.registeredAt - b.registeredAt); for (const plugin of pluginList) { if (plugin.disabled) { return; } for (const callback of CALLBACK_LIST) { if (plugin[callback] && plugin.id) { this[callback].push(plugin.id); } } } } hasPlugins(callbackType) { return this[callbackType].length > 0; } countPlugins(callbackType) { if (callbackType) { return this[callbackType].length; } return Object.keys(this.idToPlugin).length; } addPlugins(plugins) { this.mapPlugins(plugins); this.indexPlugins(); } enablePlugin(id) { const plugin = this.idToPlugin[id]; if (plugin) { plugin.disabled = false; } this.indexPlugins(); } disablePlugin(id) { const plugin = this.idToPlugin[id]; if (plugin) { plugin.disabled = true; } this.indexPlugins(); } removePlugin(id) { delete this.idToPlugin[id]; this.indexPlugins(); } /** * Runs plugins that defines onBeforeDataOut. */ runOnBeforeDataOut(params, loglayer) { const initialData = { ...params }; for (const pluginId of this.onBeforeDataOut) { const plugin = this.idToPlugin[pluginId]; if (plugin.onBeforeDataOut) { const result = plugin.onBeforeDataOut( { data: initialData.data, logLevel: initialData.logLevel }, loglayer ); if (result) { if (!initialData.data) { initialData.data = {}; } Object.assign(initialData.data, result); } } } return initialData.data; } /** * Runs plugins that define shouldSendToLogger. Any plugin that returns false will prevent the message from being sent to the transport. */ runShouldSendToLogger(params, loglayer) { return !this.shouldSendToLogger.some((pluginId) => { const plugin = this.idToPlugin[pluginId]; return !_optionalChain([plugin, 'access', _ => _.shouldSendToLogger, 'optionalCall', _2 => _2(params, loglayer)]); }); } /** * Runs plugins that define onMetadataCalled. */ runOnMetadataCalled(metadata, loglayer) { let data = { ...metadata }; for (const pluginId of this.onMetadataCalled) { const plugin = this.idToPlugin[pluginId]; const result = _optionalChain([plugin, 'access', _3 => _3.onMetadataCalled, 'optionalCall', _4 => _4(data, loglayer)]); if (result) { data = result; } else { return null; } } return data; } runOnBeforeMessageOut(params, loglayer) { let messages = [...params.messages]; for (const pluginId of this.onBeforeMessageOut) { const plugin = this.idToPlugin[pluginId]; const result = _optionalChain([plugin, 'access', _5 => _5.onBeforeMessageOut, 'optionalCall', _6 => _6( { messages, logLevel: params.logLevel }, loglayer )]); if (result) { messages = result; } } return messages; } /** * Runs plugins that define onContextCalled. */ runOnContextCalled(context, loglayer) { let data = { ...context }; for (const pluginId of this.onContextCalled) { const plugin = this.idToPlugin[pluginId]; const result = _optionalChain([plugin, 'access', _7 => _7.onContextCalled, 'optionalCall', _8 => _8(data, loglayer)]); if (result) { data = result; } else { return null; } } return data; } }, _class); // src/LogLayer.ts var LogLayer = (_class2 = class _LogLayer { __init6() {this.logLevelEnabledStatus = { info: true, warn: true, error: true, debug: true, trace: true, fatal: true }} /** * The configuration object used to initialize the logger. * This is for internal use only and should not be modified directly. */ constructor(config) {;_class2.prototype.__init6.call(this); this._config = { ...config, enabled: _nullishCoalesce(config.enabled, () => ( true)) }; if (!this._config.enabled) { this.disableLogging(); } this.contextManager = new (0, _contextmanager.DefaultContextManager)(); this.pluginManager = new PluginManager(config.plugins || []); if (!this._config.errorFieldName) { this._config.errorFieldName = "err"; } if (!this._config.copyMsgOnOnlyError) { this._config.copyMsgOnOnlyError = false; } this._initializeTransports(this._config.transport); } /** * Sets the context manager to use for managing context data. */ withContextManager(contextManager) { if (this.contextManager && typeof this.contextManager[Symbol.dispose] === "function") { this.contextManager[Symbol.dispose](); } this.contextManager = contextManager; return this; } /** * Returns the context manager instance being used. */ getContextManager() { return this.contextManager; } _initializeTransports(transports) { if (this.idToTransport) { for (const id in this.idToTransport) { if (this.idToTransport[id] && typeof this.idToTransport[id][Symbol.dispose] === "function") { this.idToTransport[id][Symbol.dispose](); } } } this.hasMultipleTransports = Array.isArray(transports) && transports.length > 1; this.singleTransport = this.hasMultipleTransports ? null : Array.isArray(transports) ? transports[0] : transports; if (Array.isArray(transports)) { this.idToTransport = transports.reduce((acc, transport) => { acc[transport.id] = transport; return acc; }, {}); } else { this.idToTransport = { [transports.id]: transports }; } } /** * Calls child() and sets the prefix to be included with every log message. * * @see {@link https://loglayer.dev/logging-api/basic-logging.html#message-prefixing | Message Prefixing Docs} */ withPrefix(prefix) { const logger = this.child(); logger._config.prefix = prefix; return logger; } /** * Appends context data which will be included with * every log entry. * * Passing in an empty value / object will *not* clear the context. * * To clear the context, use {@link https://loglayer.dev/logging-api/context.html#clearing-context | clearContext()}. * * @see {@link https://loglayer.dev/logging-api/context.html | Context Docs} */ withContext(context) { let updatedContext = context; if (!context) { if (this._config.consoleDebug) { console.debug("[LogLayer] withContext was called with no context; dropping."); } return this; } if (this.pluginManager.hasPlugins(_plugin.PluginCallbackType.onContextCalled)) { updatedContext = this.pluginManager.runOnContextCalled(context, this); if (!updatedContext) { if (this._config.consoleDebug) { console.debug("[LogLayer] Context was dropped due to plugin returning falsy value."); } return this; } } this.contextManager.appendContext(updatedContext); return this; } /** * Clears the context data. */ clearContext() { this.contextManager.setContext(void 0); return this; } getContext() { return this.contextManager.getContext(); } /** * Add additional plugins. * * @see {@link https://loglayer.dev/plugins/ | Plugins Docs} */ addPlugins(plugins) { this.pluginManager.addPlugins(plugins); } /** * Enables a plugin by id. * * @see {@link https://loglayer.dev/plugins/ | Plugins Docs} */ enablePlugin(id) { this.pluginManager.enablePlugin(id); } /** * Disables a plugin by id. * * @see {@link https://loglayer.dev/plugins/ | Plugins Docs} */ disablePlugin(id) { this.pluginManager.disablePlugin(id); } /** * Removes a plugin by id. * * @see {@link https://loglayer.dev/plugins/ | Plugins Docs} */ removePlugin(id) { this.pluginManager.removePlugin(id); } /** * Specifies metadata to include with the log message * * @see {@link https://loglayer.dev/logging-api/metadata.html | Metadata Docs} */ withMetadata(metadata) { return new LogBuilder(this).withMetadata(metadata); } /** * Specifies an Error to include with the log message * * @see {@link https://loglayer.dev/logging-api/error-handling.html | Error Handling Docs} */ withError(error) { return new LogBuilder(this).withError(error); } /** * Creates a new instance of LogLayer but with the initialization * configuration and context copied over. * * @see {@link https://loglayer.dev/logging-api/child-loggers.html | Child Logging Docs} */ child() { const childConfig = { ...this._config, transport: Array.isArray(this._config.transport) ? [...this._config.transport] : this._config.transport }; const childLogger = new _LogLayer(childConfig).withPluginManager(this.pluginManager).withContextManager(this.contextManager.clone()); this.contextManager.onChildLoggerCreated({ parentContextManager: this.contextManager, childContextManager: childLogger.contextManager, parentLogger: this, childLogger }); return childLogger; } /** * Replaces all existing transports with new ones. * * When used with child loggers, it only affects the current logger instance * and does not modify the parent's transports. * * @see {@link https://loglayer.dev/logging-api/transport-management.html | Transport Management Docs} */ withFreshTransports(transports) { this._config.transport = transports; this._initializeTransports(transports); return this; } /** * Replaces all existing plugins with new ones. * * When used with child loggers, it only affects the current logger instance * and does not modify the parent's plugins. * * @see {@link https://loglayer.dev/plugins/ | Plugins Docs} */ withFreshPlugins(plugins) { this._config.plugins = plugins; this.pluginManager = new PluginManager(plugins); return this; } withPluginManager(pluginManager) { this.pluginManager = pluginManager; return this; } /** * Logs only the error object without a log message * * @see {@link https://loglayer.dev/logging-api/error-handling.html | Error Handling Docs} */ errorOnly(error, opts) { const logLevel = _optionalChain([opts, 'optionalAccess', _9 => _9.logLevel]) || _shared.LogLevel.error; if (!this.isLevelEnabled(logLevel)) return; const { copyMsgOnOnlyError } = this._config; const formatLogConf = { logLevel, err: error }; if ((copyMsgOnOnlyError && _optionalChain([opts, 'optionalAccess', _10 => _10.copyMsg]) !== false || _optionalChain([opts, 'optionalAccess', _11 => _11.copyMsg]) === true) && _optionalChain([error, 'optionalAccess', _12 => _12.message])) { formatLogConf.params = [error.message]; } this._formatLog(formatLogConf); } /** * Logs only metadata without a log message * * @see {@link https://loglayer.dev/logging-api/metadata.html | Metadata Docs} */ metadataOnly(metadata, logLevel = _shared.LogLevel.info) { if (!this.isLevelEnabled(logLevel)) return; const { muteMetadata, consoleDebug } = this._config; if (muteMetadata) { return; } if (!metadata) { if (consoleDebug) { console.debug("[LogLayer] metadataOnly was called with no metadata; dropping."); } return; } let data = metadata; if (this.pluginManager.hasPlugins(_plugin.PluginCallbackType.onMetadataCalled)) { data = this.pluginManager.runOnMetadataCalled(metadata, this); if (!data) { if (consoleDebug) { console.debug("[LogLayer] Metadata was dropped due to plugin returning falsy value."); } return; } } const config = { logLevel, metadata: data }; this._formatLog(config); } /** * Sends a log message to the logging library under an info log level. * * The logging library may or may not support multiple message parameters and only * the first parameter would be used. * * @see {@link https://loglayer.dev/logging-api/basic-logging.html | Basic Logging Docs} */ info(...messages) { if (!this.isLevelEnabled(_shared.LogLevel.info)) return; this._formatMessage(messages); this._formatLog({ logLevel: _shared.LogLevel.info, params: messages }); } /** * Sends a log message to the logging library under the warn log level * * @see {@link https://loglayer.dev/logging-api/basic-logging.html | Basic Logging Docs} */ warn(...messages) { if (!this.isLevelEnabled(_shared.LogLevel.warn)) return; this._formatMessage(messages); this._formatLog({ logLevel: _shared.LogLevel.warn, params: messages }); } /** * Sends a log message to the logging library under the error log level * * @see {@link https://loglayer.dev/logging-api/basic-logging.html | Basic Logging Docs} */ error(...messages) { if (!this.isLevelEnabled(_shared.LogLevel.error)) return; this._formatMessage(messages); this._formatLog({ logLevel: _shared.LogLevel.error, params: messages }); } /** * Sends a log message to the logging library under the debug log level * * @see {@link https://loglayer.dev/logging-api/basic-logging.html | Basic Logging Docs} */ debug(...messages) { if (!this.isLevelEnabled(_shared.LogLevel.debug)) return; this._formatMessage(messages); this._formatLog({ logLevel: _shared.LogLevel.debug, params: messages }); } /** * Sends a log message to the logging library under the trace log level * * @see {@link https://loglayer.dev/logging-api/basic-logging.html | Basic Logging Docs} */ trace(...messages) { if (!this.isLevelEnabled(_shared.LogLevel.trace)) return; this._formatMessage(messages); this._formatLog({ logLevel: _shared.LogLevel.trace, params: messages }); } /** * Sends a log message to the logging library under the fatal log level * * @see {@link https://loglayer.dev/logging-api/basic-logging.html | Basic Logging Docs} */ fatal(...messages) { if (!this.isLevelEnabled(_shared.LogLevel.fatal)) return; this._formatMessage(messages); this._formatLog({ logLevel: _shared.LogLevel.fatal, params: messages }); } /** * All logging inputs are dropped and stops sending logs to the logging library. * * @see {@link https://loglayer.dev/logging-api/basic-logging.html#enabling-disabling-logging | Enabling/Disabling Logging Docs} */ disableLogging() { for (const level of Object.keys(this.logLevelEnabledStatus)) { this.logLevelEnabledStatus[level] = false; } return this; } /** * Enable sending logs to the logging library. * * @see {@link https://loglayer.dev/logging-api/basic-logging.html#enabling-disabling-logging | Enabling/Disabling Logging Docs} */ enableLogging() { for (const level of Object.keys(this.logLevelEnabledStatus)) { this.logLevelEnabledStatus[level] = true; } return this; } /** * Disables inclusion of context data in the print * * @see {@link https://loglayer.dev/logging-api/context.html#managing-context | Managing Context Docs} */ muteContext() { this._config.muteContext = true; return this; } /** * Enables inclusion of context data in the print * * @see {@link https://loglayer.dev/logging-api/context.html#managing-context | Managing Context Docs} */ unMuteContext() { this._config.muteContext = false; return this; } /** * Disables inclusion of metadata in the print * * @see {@link https://loglayer.dev/logging-api/metadata.html#controlling-metadata-output | Controlling Metadata Output Docs} */ muteMetadata() { this._config.muteMetadata = true; return this; } /** * Enables inclusion of metadata in the print * * @see {@link https://loglayer.dev/logging-api/metadata.html#controlling-metadata-output | Controlling Metadata Output Docs} */ unMuteMetadata() { this._config.muteMetadata = false; return this; } /** * Enables a specific log level * * @see {@link https://loglayer.dev/logging-api/basic-logging.html#enabling-disabling-logging | Enabling/Disabling Logging Docs} */ enableIndividualLevel(logLevel) { const level = logLevel; if (level in this.logLevelEnabledStatus) { this.logLevelEnabledStatus[level] = true; } return this; } /** * Disables a specific log level * * @see {@link https://loglayer.dev/logging-api/basic-logging.html#enabling-disabling-logging | Enabling/Disabling Logging Docs} */ disableIndividualLevel(logLevel) { const level = logLevel; if (level in this.logLevelEnabledStatus) { this.logLevelEnabledStatus[level] = false; } return this; } /** * Sets the minimum log level to be used by the logger. Only messages with * this level or higher severity will be logged. * * For example, if you setLevel(LogLevel.warn), this will: * Enable: * - warn * - error * - fatal * Disable: * - info * - debug * - trace * * @see {@link https://loglayer.dev/logging-api/basic-logging.html#enabling-disabling-logging | Enabling/Disabling Logging Docs} */ setLevel(logLevel) { const minLogValue = _shared.LogLevelPriority[logLevel]; for (const level of Object.values(_shared.LogLevel)) { const levelKey = level; const levelValue = _shared.LogLevelPriority[level]; this.logLevelEnabledStatus[levelKey] = levelValue >= minLogValue; } return this; } /** * Checks if a specific log level is enabled * * @see {@link https://loglayer.dev/logging-api/basic-logging.html#checking-if-a-log-level-is-enabled | Checking if a Log Level is Enabled Docs} */ isLevelEnabled(logLevel) { const level = logLevel; return this.logLevelEnabledStatus[level]; } formatContext() { const { contextFieldName, muteContext } = this._config; const context = this.contextManager.getContext(); if (this.contextManager.hasContextData() && !muteContext) { if (contextFieldName) { return { [contextFieldName]: { ...context } }; } return { ...context }; } return {}; } formatMetadata(data = null) { const { metadataFieldName, muteMetadata } = this._config; if (data && !muteMetadata) { if (metadataFieldName) { return { [metadataFieldName]: { ...data } }; } return { ...data }; } return {}; } /** * Returns a logger instance for a specific transport * * @see {@link https://loglayer.dev/logging-api/transport-management.html | Transport Management Docs} */ getLoggerInstance(id) { const transport = this.idToTransport[id]; if (!transport) { return void 0; } return transport.getLoggerInstance(); } _formatMessage(messages = []) { const { prefix } = this._config; if (prefix && typeof messages[0] === "string") { messages[0] = `${prefix} ${messages[0]}`; } } _formatLog({ logLevel, params = [], metadata = null, err }) { const { errorSerializer, errorFieldInMetadata, muteContext, contextFieldName, metadataFieldName, errorFieldName } = this._config; let hasObjData = !!metadata || (muteContext ? false : this.contextManager.hasContextData()); let d = {}; if (hasObjData) { if (contextFieldName && contextFieldName === metadataFieldName) { const contextData = this.formatContext()[contextFieldName]; const updatedMetadata = this.formatMetadata(metadata)[metadataFieldName]; d = { [contextFieldName]: { ...contextData, ...updatedMetadata } }; } else { d = { ...this.formatContext(), ...this.formatMetadata(metadata) }; } } if (err) { const serializedError = errorSerializer ? errorSerializer(err) : err; if (errorFieldInMetadata && metadata) { metadata[errorFieldName] = serializedError; } else if (errorFieldInMetadata && !metadata && metadataFieldName) { d = { ...d, [metadataFieldName]: { [errorFieldName]: serializedError } }; } else { d = { ...d, [errorFieldName]: serializedError }; } hasObjData = true; } if (this.pluginManager.hasPlugins(_plugin.PluginCallbackType.onBeforeDataOut)) { d = this.pluginManager.runOnBeforeDataOut( { data: hasObjData ? d : void 0, logLevel }, this ); if (d && !hasObjData) { hasObjData = true; } } if (this.pluginManager.hasPlugins(_plugin.PluginCallbackType.onBeforeMessageOut)) { params = this.pluginManager.runOnBeforeMessageOut( { messages: [...params], logLevel }, this ); } if (this.hasMultipleTransports) { const transportPromises = this._config.transport.filter((transport) => transport.enabled).map(async (transport) => { if (this.pluginManager.hasPlugins(_plugin.PluginCallbackType.shouldSendToLogger)) { const shouldSend = this.pluginManager.runShouldSendToLogger( { messages: [...params], data: hasObjData ? d : void 0, logLevel, transportId: transport.id }, this ); if (!shouldSend) { return; } } return transport._sendToLogger({ logLevel, messages: [...params], data: hasObjData ? d : void 0, hasData: hasObjData }); }); Promise.all(transportPromises).catch((err2) => { if (this._config.consoleDebug) { console.error("[LogLayer] Error executing transports:", err2); } }); } else { if (!_optionalChain([this, 'access', _13 => _13.singleTransport, 'optionalAccess', _14 => _14.enabled])) { return; } if (this.pluginManager.hasPlugins(_plugin.PluginCallbackType.shouldSendToLogger)) { const shouldSend = this.pluginManager.runShouldSendToLogger( { messages: [...params], data: hasObjData ? d : void 0, logLevel, transportId: this.singleTransport.id }, this ); if (!shouldSend) { return; } } this.singleTransport._sendToLogger({ logLevel, messages: [...params], data: hasObjData ? d : void 0, hasData: hasObjData }); } } }, _class2); // src/MockLogBuilder.ts var MockLogBuilder = class { debug(..._messages) { } error(..._messages) { } info(..._messages) { } trace(..._messages) { } warn(..._messages) { } fatal(..._messages) { } enableLogging() { return this; } disableLogging() { return this; } withMetadata(_metadata) { return this; } withError(_error) { return this; } }; // src/MockLogLayer.ts var MockLogLayer = (_class3 = class {constructor() { _class3.prototype.__init7.call(this); } __init7() {this.mockLogBuilder = new MockLogBuilder()} info(..._messages) { } warn(..._messages) { } error(..._messages) { } debug(..._messages) { } trace(..._messages) { } fatal(..._messages) { } getLoggerInstance(_id) { return void 0; } errorOnly(_error, _opts) { } metadataOnly(_metadata, _logLevel) { } addPlugins(_plugins) { } removePlugin(_id) { } enablePlugin(_id) { } disablePlugin(_id) { } withPrefix(_prefix) { return this; } withContext(_context) { return this; } withError(error) { this.mockLogBuilder.withError(error); return this.mockLogBuilder; } withMetadata(metadata) { this.mockLogBuilder.withMetadata(metadata); return this.mockLogBuilder; } getContext() { return {}; } clearContext() { return this; } enableLogging() { return this; } disableLogging() { return this; } child() { return this; } muteContext() { return this; } unMuteContext() { return this; } muteMetadata() { return this; } unMuteMetadata() { return this; } withFreshTransports(_transports) { return this; } withFreshPlugins(_plugins) { return this; } withContextManager(_contextManager) { return this; } getContextManager() { return void 0; } /** * Sets the mock log builder to use for testing. */ setMockLogBuilder(mockLogBuilder) { this.mockLogBuilder = mockLogBuilder; } enableIndividualLevel(_logLevel) { return this; } disableIndividualLevel(_logLevel) { return this; } setLevel(_logLevel) { return this; } isLevelEnabled(_logLevel) { return true; } /** * Returns the mock log builder used for testing. */ getMockLogBuilder() { return this.mockLogBuilder; } /** * Resets the mock log builder to a new instance of MockLogBuilder. */ resetMockLogBuilder() { this.mockLogBuilder = new MockLogBuilder(); } }, _class3); // src/TestLoggingLibrary.ts var TestLoggingLibrary = class { /** * An array of log lines that have been logged. */ constructor() { this.lines = []; } info(...params) { this.addLine(_shared.LogLevel.info, params); } warn(...params) { this.addLine(_shared.LogLevel.warn, params); } error(...params) { this.addLine(_shared.LogLevel.error, params); } debug(...params) { this.addLine(_shared.LogLevel.debug, params); } trace(...params) { this.addLine(_shared.LogLevel.trace, params); } fatal(...params) { this.addLine(_shared.LogLevel.fatal, params); } addLine(logLevel, params) { this.lines.push({ level: logLevel, data: params }); } /** * Get the last line that was logged. Returns null if no lines have been logged. */ getLastLine() { if (!this.lines.length) { return null; } return this.lines[this.lines.length - 1]; } /** * Pops the last line that was logged. Returns null if no lines have been logged. */ popLine() { return this.lines.pop(); } /** * Clears all lines that have been logged. */ clearLines() { this.lines = []; } }; // src/transports/BlankTransport.ts var _transport = require('@loglayer/transport'); var BlankTransport = class extends _transport.LoggerlessTransport { constructor(config) { super(config); this.shipToLoggerFn = config.shipToLogger; } shipToLogger(params) { return this.shipToLoggerFn(params); } }; // src/transports/ConsoleTransport.ts var ConsoleTransport = class extends _transport.BaseTransport { constructor(params) { super(params); this.appendObjectData = params.appendObjectData || false; this.logLevel = _nullishCoalesce(params.level, () => ( "trace")); this.messageField = params.messageField; this.dateField = params.dateField; this.levelField = params.levelField; this.dateFn = params.dateFn; this.levelFn = params.levelFn; } shipToLogger({ logLevel, messages, data, hasData }) { if (_transport.LogLevelPriority[logLevel] < _transport.LogLevelPriority[this.logLevel]) { return; } if (this.messageField || this.dateField || this.levelField) { const messageText = this.messageField ? messages.join(" ") : void 0; const logObject = { ...data || {}, ...this.messageField && { [this.messageField]: messageText }, ...this.dateField && { [this.dateField]: this.dateFn ? this.dateFn() : (/* @__PURE__ */ new Date()).toISOString() }, ...this.levelField && { [this.levelField]: this.levelFn ? this.levelFn(logLevel) : logLevel } }; messages = [logObject]; } else if (data && hasData) { if (this.appendObjectData) { messages.push(data); } else { messages.unshift(data); } } switch (logLevel) { case _shared.LogLevel.info: this.logger.info(...messages); break; case _shared.LogLevel.warn: this.logger.warn(...messages); break; case _shared.LogLevel.error: this.logger.error(...messages); break; case _shared.LogLevel.trace: this.logger.trace(...messages); break; case _shared.LogLevel.debug: this.logger.debug(...messages); break; case _shared.LogLevel.fatal: this.logger.error(...messages); break; } return messages; } }; // src/transports/TestTransport.ts var TestTransport = class extends _transport.BaseTransport { shipToLogger({ logLevel, messages, data, hasData }) { if (data && hasData) { messages.unshift(data); } switch (logLevel) { case _shared.LogLevel.info: this.logger.info(...messages); break; case _shared.LogLevel.warn: this.logger.warn(...messages); break; case _shared.LogLevel.error: this.logger.error(...messages); break; case _shared.LogLevel.trace: this.logger.trace(...messages); break; case _shared.LogLevel.debug: this.logger.debug(...messages); break; case _shared.LogLevel.fatal: this.logger.fatal(...messages); break; } return messages; } }; exports.BlankTransport = BlankTransport; exports.ConsoleTransport = ConsoleTransport; exports.LogLayer = LogLayer; exports.LogLevel = _shared.LogLevel; exports.MockLogBuilder = MockLogBuilder; exports.MockLogLayer = MockLogLayer; exports.PluginCallbackType = _plugin.PluginCallbackType; exports.TestLoggingLibrary = TestLoggingLibrary; exports.TestTransport = TestTransport;