UNPKG

knxultimate

Version:

KNX IP protocol implementation for Node. This is the ENGINE of Node-Red KNX-Ultimate node.

126 lines (103 loc) 3.15 kB
/** * Centralized logging utility for KNXUltimate. * * Written in Italy with love, sun and passion, by Massimo Saccani. * * Released under the MIT License. * Use at your own risk; the author assumes no liability for damages. */ import winston, { Container, Logform, Logger, transport } from 'winston' import { PassThrough } from 'stream' const { format, transports, addColors } = winston const { combine, timestamp, label, printf, colorize, splat } = format const colorizer = colorize() const MODULES = process.env.LOG_MODULES ? process.env.LOG_MODULES.split(',').map((m) => m.trim().toUpperCase()) : null export const logStream = new PassThrough({ objectMode: true }) export interface KNXLogger extends Logger { module: string } export interface KNXLoggerContainer extends winston.Container { loggers: Map<string, KNXLogger> } export type LogLevel = 'disable' | 'error' | 'warn' | 'info' | 'debug' | 'trace' export type KNXLoggerOptions = { loglevel?: LogLevel setPrefix?: string } export function setLogLevel(level: LogLevel) { logContainer.loggers.forEach((logger) => { const transportsList = logger.transports transportsList.forEach((t) => { t.level = level }) logger.configure({ level, transports: transportsList }) }) } // Custom colors addColors({ time: 'grey', module: 'bold', }) export function customKNXFormat(moduleName: string): Logform.Format { return combine( splat(), timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }), format((info: winston.Logform.TransformableInfo) => { info.level = info.level.toUpperCase() return info })(), label({ label: moduleName.toUpperCase() }), colorize({ level: true }), printf((info: winston.Logform.TransformableInfo) => { info.timestamp = colorizer.colorize( 'time', info.timestamp as string, ) info.label = colorizer.colorize( 'module', (info.label || '-') as string, ) return `${info.timestamp} ${info.level} ${info.label}: ${info.message}${info.stack ? `\n${info.stack}` : ''}` }), ) } const logModules = (moduleName: string): Logform.Format => format((info) => !MODULES || MODULES.find((c) => moduleName.toUpperCase().startsWith(c)) ? info : false, )() export function customTransports(moduleName: string): transport[] { const formats = MODULES ? [logModules(moduleName)] : [] formats.push(customKNXFormat(moduleName)) const transportsList: transport[] = [ new transports.Console({ format: combine(...formats), level: process.env.LOG_LEVEL || 'info', stderrLevels: ['error'], }), new winston.transports.Stream({ stream: logStream, format: combine(...formats), }), ] return transportsList } export function setupLogger( container: Container, moduleName: string, ): KNXLogger { const logger = container.add(moduleName) as KNXLogger logger.configure({ transports: customTransports(moduleName), }) logger.module = moduleName return logger } const logContainer = new winston.Container() as KNXLoggerContainer export function module(moduleName: string): KNXLogger { return setupLogger(logContainer, moduleName) } export default logContainer.loggers