UNPKG

@livy/logger

Version:

A Monolog-inspired logging library for Node.js

237 lines (236 loc) 7.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AbstractLogger = void 0; const log_level_1 = require("@livy/contracts/lib/log-level"); const environment = __importStar(require("@livy/util/lib/environment")); const is_closable_handler_interface_1 = require("@livy/util/lib/handlers/is-closable-handler-interface"); const helpers_1 = require("@livy/util/lib/helpers"); const is_resettable_interface_1 = require("@livy/util/lib/is-resettable-interface"); const validatable_set_1 = require("@livy/util/lib/validatable-set"); const luxon = __importStar(require("luxon")); /** * A base logger class with all functionalities common to sync, async and mixed loggers */ class AbstractLogger { /** * The handler attached to the program exit event */ static exitHandler() { // istanbul ignore next: Unloading is hard to test for (const logger of AbstractLogger.openLoggers) { logger.close(); } } /** * Clear registered exit handlers * This is mostly useful for unit testing */ static clearExitHandlers() { // istanbul ignore next: Unloading is hard to test if (AbstractLogger.openLoggers.length > 0) { AbstractLogger.openLoggers.splice(0); if (environment.isNodeJs) { process.removeListener('exit', AbstractLogger.exitHandler); } else if (environment.isBrowser) { self.removeEventListener('unload', AbstractLogger.exitHandler); } } } constructor(_name, { autoClose = true, handlers = [], processors = [], timezone = luxon.Settings.defaultZoneName } = {}) { this._name = _name; this._handlers = new validatable_set_1.ValidatableSet(handlers); this._processors = new Set(processors); this.timezone = timezone; if (autoClose) { this.closeOnExit(); } } /** * Get the logger's channel name */ get name() { return this._name; } /** * Get the logger's timezone */ get timezone() { return this._timezone; } /** * Set the logger's timezone */ set timezone(value) { // This throws an error if the timezone is invalid if (!luxon.IANAZone.isValidZone(value)) { throw new Error(`Invalid timezone "${value}"`); } this._timezone = value; } /** * Get the handlers attached to the logger */ get handlers() { return this._handlers; } /** * Get the processors attached to the logger */ get processors() { return this._processors; } /** * Close when the program terminates */ closeOnExit() { if (AbstractLogger.openLoggers.length === 0) { // istanbul ignore else: Simulating browser unloading is too hard to test if (environment.isNodeJs) { process.on('exit', AbstractLogger.exitHandler); } else if (environment.isBrowser) { self.addEventListener('unload', AbstractLogger.exitHandler); } } AbstractLogger.openLoggers.push(this); } /** * Close all registered handlers */ close() { for (const handler of this._handlers) { if ((0, is_closable_handler_interface_1.isClosableHandlerInterface)(handler)) { handler.close(); } } } /** * Reset all registered handlers and processors */ reset() { for (const handler of this._handlers) { if ((0, is_resettable_interface_1.isResettableInterface)(handler)) { handler.reset(); } } for (const processor of this._processors) { if ((0, is_resettable_interface_1.isResettableInterface)(processor)) { processor.reset(); } } } /** * Checks whether the logger has a handler that listens on the given level */ isHandling(level) { return (this._handlers.size > 0 && [...this._handlers].some(handler => handler.isHandling(level))); } /** * @inheritdoc */ log(level, message, context = {}) { if (!log_level_1.logLevels.includes(level)) { throw new Error(`Invalid log level "${level}", use one of: ${log_level_1.logLevels.join(', ')}`); } if (!(0, helpers_1.isPrimitive)(message)) { throw new Error(`Log message must be a primitive, ${(0, helpers_1.getObviousTypeName)(message)} given`); } let record = { level, severity: log_level_1.SeverityMap[level], message: String(message), context, extra: {}, datetime: luxon.DateTime.local().setZone(this._timezone), channel: this._name }; // Apply global processors for (const processor of this._processors) { if (typeof processor === 'function') { record = processor(record); } else { record = processor.process(record); } } return this.runHandlers(record); } /** * @inheritdoc */ emergency(message, context = {}) { return this.log('emergency', message, context); } /** * @inheritdoc */ alert(message, context = {}) { return this.log('alert', message, context); } /** * @inheritdoc */ critical(message, context = {}) { return this.log('critical', message, context); } /** * @inheritdoc */ error(message, context = {}) { return this.log('error', message, context); } /** * @inheritdoc */ warning(message, context = {}) { return this.log('warning', message, context); } /** * @inheritdoc */ notice(message, context = {}) { return this.log('notice', message, context); } /** * @inheritdoc */ info(message, context = {}) { return this.log('info', message, context); } /** * @inheritdoc */ debug(message, context = {}) { return this.log('debug', message, context); } } exports.AbstractLogger = AbstractLogger; /** * A list of currently unclosed loggers which should be closed on exit */ AbstractLogger.openLoggers = [];