UNPKG

@backstage/backend-defaults

Version:

Backend defaults used by Backstage backend apps

124 lines (120 loc) 3.8 kB
'use strict'; var winston = require('winston'); var tripleBeam = require('triple-beam'); var escapeRegExp = require('../../lib/escapeRegExp.cjs.js'); class WinstonLogger { #winston; #addRedactions; /** * Creates a {@link WinstonLogger} instance. */ static create(options) { const redacter = WinstonLogger.redacter(); const defaultFormatter = process.env.NODE_ENV === "production" ? winston.format.json() : WinstonLogger.colorFormat(); let logger = winston.createLogger({ level: process.env.LOG_LEVEL || options.level || "info", format: winston.format.combine( options.format ?? defaultFormatter, redacter.format ), transports: options.transports ?? new winston.transports.Console() }); if (options.meta) { logger = logger.child(options.meta); } return new WinstonLogger(logger, redacter.add); } /** * Creates a winston log formatter for redacting secrets. */ static redacter() { const redactionSet = /* @__PURE__ */ new Set(); let redactionPattern = void 0; return { format: winston.format((obj) => { if (!redactionPattern || !obj) { return obj; } obj[tripleBeam.MESSAGE] = obj[tripleBeam.MESSAGE]?.replace?.(redactionPattern, "***"); return obj; })(), add(newRedactions) { let added = 0; for (const redactionToTrim of newRedactions) { if (redactionToTrim === null || redactionToTrim === void 0) { continue; } const redaction = redactionToTrim.trim(); if (redaction.length <= 1) { continue; } if (!redactionSet.has(redaction)) { redactionSet.add(redaction); added += 1; } } if (added > 0) { const redactions = Array.from(redactionSet).map((r) => escapeRegExp.escapeRegExp(r)).join("|"); redactionPattern = new RegExp(`(${redactions})`, "g"); } } }; } /** * Creates a pretty printed winston log formatter. */ static colorFormat() { const colorizer = winston.format.colorize(); return winston.format.combine( winston.format.timestamp(), winston.format.colorize({ colors: { timestamp: "dim", prefix: "blue", field: "cyan", debug: "grey" } }), winston.format.printf((info) => { const { timestamp, level, message, plugin, service, ...fields } = info; const prefix = plugin || service; const timestampColor = colorizer.colorize("timestamp", timestamp); const prefixColor = colorizer.colorize("prefix", prefix); const extraFields = Object.entries(fields).map(([key, value]) => { let stringValue = ""; try { stringValue = JSON.stringify(value); } catch (e) { stringValue = "[field value not castable to string]"; } return `${colorizer.colorize("field", `${key}`)}=${stringValue}`; }).join(" "); return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`; }) ); } constructor(winston, addRedactions) { this.#winston = winston; this.#addRedactions = addRedactions; } error(message, meta) { this.#winston.error(message, meta); } warn(message, meta) { this.#winston.warn(message, meta); } info(message, meta) { this.#winston.info(message, meta); } debug(message, meta) { this.#winston.debug(message, meta); } child(meta) { return new WinstonLogger(this.#winston.child(meta)); } addRedactions(redactions) { this.#addRedactions?.(redactions); } } exports.WinstonLogger = WinstonLogger; //# sourceMappingURL=WinstonLogger.cjs.js.map