UNPKG

@graphile/logger

Version:

A logger abstraction for libraries

149 lines 5.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultLogger = exports.consoleLogFactory = exports.makeConsoleLogFactory = exports.Logger = exports.LogLevel = void 0; const EMPTY_OBJECT = Object.freeze({}); /** @deprecated Just use string values: "error" | "warning" | "info" | "debug". */ exports.LogLevel = Object.freeze({ /** * Critical log message indicating something unexpected went wrong. Similar * in interpretation to `console.error`. */ ERROR: "error", /** * Import log message warning of something potentially troublesome. Similar * in interpretation to `console.warn`. */ WARNING: "warning", /** * General log message for information. Similar in interpretation to * `console.log`. */ INFO: "info", /** * Particularly verbose log message, normally only needed during debugging. * Due to verbosity, you typically would not want this level to be output. * Similar in interpretation to `console.debug`. */ DEBUG: "debug", }); /** * A `Logger` is initialized with a `LogFunctionFactory` and an initial scope. * It has convenience methods for logging different levels (error, warn, info, * debug) which pass through to the underlying `LogFunction`. It also allows a * narrower scoped logger to be generated via the `scope` method. */ class Logger { constructor(logFactory, scope = {}) { this._scope = scope; this._logFactory = logFactory; this.log = logFactory(scope); } /** * Creates a more narrowly scoped logger; this is useful when your code * performs a subtask. For example: an HTTP server might have a global * logger, and it might create scoped loggers for each incoming HTTP request. * When the HTTP requests goes through a particular middleware it might use * an even more narrowly scoped logger still. */ scope(additionalScope) { return new Logger(this._logFactory, { ...this._scope, ...additionalScope, }); } /** * Logs an `"error"` message. */ error(message, meta) { return this.log("error", message, meta !== null && meta !== void 0 ? meta : EMPTY_OBJECT); } /** * Logs an `"warning"` message. */ warn(message, meta) { return this.log("warning", message, meta !== null && meta !== void 0 ? meta : EMPTY_OBJECT); } /** * Logs an `"info"` message. */ info(message, meta) { return this.log("info", message, meta !== null && meta !== void 0 ? meta : EMPTY_OBJECT); } /** * Logs an `"debug"` message. */ debug(message, meta) { return this.log("debug", message, meta !== null && meta !== void 0 ? meta : EMPTY_OBJECT); } } exports.Logger = Logger; // Reading envvars is expensive; cache it. const omitDebugLogs = !process.env.GRAPHILE_LOGGER_DEBUG; const DEFAULT_CONFIG = (level, message, scope, meta) => { const scopeString = Object.entries(scope) .map(([key, val]) => `${key}:${JSON.stringify(val)}`) .join(","); let format = "%s%s: %s"; const formatParameters = [ level.toUpperCase(), scopeString ? `[${scopeString}]` : "", message, ]; if (Object.keys(meta).length > 0) { format += " (%O)"; formatParameters.push(meta); } return { format, formatParameters }; }; /** * Lets you build a console log factory with custom log formatter. Only logs * `DEBUG` level messages if the `GRAPHILE_LOGGER_DEBUG` environmental variable * is set. */ function makeConsoleLogFactory(config = DEFAULT_CONFIG) { return function consoleLogFactory(scope) { if (typeof config === "function") { return function dynamicFormatLog(level, message, meta) { if (omitDebugLogs && level === "debug") { return; } const { format, formatParameters } = config(level, message, scope, meta); return doConsoleLog(level, format, formatParameters); }; } else { const { format, formatParameters } = config; return function fixedFormatLog(level, message, meta) { if (omitDebugLogs && level === "debug") { return; } const params = formatParameters(level, message, scope, meta); return doConsoleLog(level, format, params); }; } }; } exports.makeConsoleLogFactory = makeConsoleLogFactory; /** @internal */ function doConsoleLog(level, format, formatParameters) { const method = level === "error" || level === "info" ? level : level === "warning" ? "warn" : // `console.debug` in Node is just an alias for `console.log` anyway. "log"; console[method](format, ...formatParameters); } /** * Our built in `LogFunctionFactory` which uses `console` for logging, and only * logs `DEBUG` level messages if the `GRAPHILE_LOGGER_DEBUG` environmental * variable is set. Library authors can use this as a fallback if users don't * provide their own logger. If you want to format your logs in a particular * way, use `makeConsoleLogFactory` instead. */ exports.consoleLogFactory = makeConsoleLogFactory(); /** * A logger that can be used immediately. */ exports.defaultLogger = new Logger(exports.consoleLogFactory, {}); //# sourceMappingURL=index.js.map