Here is my favourite JS logger format setup with winston.
import winston, { format, transports } from "winston"
import { inspect } from 'util';
const { combine, timestamp, json, simple, align, printf, prettyPrint, errors, colorize } = format
const devFormat = combine(
timestamp({ format: 'HH:mm:ss.SS' }),
errors({ stack: true }),
printf((info) => {
const level = info.level ? info.level.toUpperCase() : 'UNKNOWN';
let msg = `[${info.timestamp}] [${level}]: ${info.message}`;
// Access and append Symbol(splat) data if it exists
const splatData = info[Symbol.for('splat')];
if (splatData && Array.isArray(splatData) && splatData.length > 0) {
const additionalData = splatData.map((item) => {
return inspect(item, {
colors: true,
depth: null,
compact: false
})
}).join(' ');
msg += `\n${additionalData}`;
}
return msg;
}),
colorize({
all: true,
}))
const prodFormat = combine(
timestamp(),
json()
)
const logger = winston.createLogger({
level: "silly",
defaultMeta: { service: "random-service" },
format: process.env.NODE_ENV === 'production' ? prodFormat : devFormat,
transports: [
new winston.transports.Console()
]
})
logger.info("Hello, world!")
logger.error("Hello, world!", new Error("test"))
logger.error(new Error("test"))
logger.info("Hello, world!", {
tag: "test",
})
logger.info("Hello, world!", {
tag: "test",
})
logger.warn("Hello, world!", {
tag: "test",
})
logger.debug("Hello, world!", {
tag: "test",
})
logger.silly("Hello, world!", {
tag: "test",
})