@graphile/logger
Version:
A logger abstraction for libraries
149 lines • 5.51 kB
JavaScript
;
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