import * as expressWinston from 'express-winston' import winston from 'winston' const LogDNATransport = require('logdna-winston') export const HEALTHCHECK_URL = '/zhealth' function inDebugMode() { return process.env.DEBUG_LOG !== 'false'; } // by default all logs unless ENV variable DEBUG=false is set const logLevel = inDebugMode() ? 'debug' : 'info' export const createLogger = (remoteAppName?: string, label?: string) : winston.Logger => { return winston.createLogger({ level: logLevel, exitOnError: false, transports: getTransports(getFormat(label), remoteAppName), handleExceptions: true, }) } // logger for use as a middleware in express export const createWWWLogger = (remoteAppName?: string) => { return expressWinston.logger({ transports: getTransports(getFormat(), remoteAppName), meta: true, requestField: inDebugMode() ? 'req' : null , msg: 'HTTP {{req.method}} {{req.url}}', expressFormat: true, colorize: true, dynamicMeta: (req) => { // we remove most of the fields from the meta and keep a couple of them for debugging const meta: Record = {} if (req) { meta.remoteIp = req.header('do-connecting-ip') || req.header('x-forwarded-for') || req.ip meta.userAgent = req.header('user-agent') meta.referrer = req.header('referer') } return meta }, ignoreRoute: function (req, res) { return [HEALTHCHECK_URL].includes(req.url) }, // skip some log messages based on request and/or response }) } function getFormat(label?: string) { const formats = [] if (process.env.NODE_ENV !== 'production') { formats.push(winston.format.colorize()) } if (label) { formats.push(winston.format.label({label: label, message: true})) } return winston.format.combine(...formats, winston.format.simple()) } function getTransports(format: winston.Logform.Format, remoteAppName?: string) { const baseTransports = [new winston.transports.Console({format: format})] // ship to logDNA.com if env var is set if (process.env.LOGDNAKEY && remoteAppName) { baseTransports.push( new LogDNATransport({ app: remoteAppName, key: process.env.LOGDNAKEY, level: logLevel, handleExceptions: true, exitOnError: false, indexMeta: true, }) ) } return baseTransports; }