@bernierllc/logging
Version:
A comprehensive logging package with Winston integration for audit and system logging
147 lines (146 loc) • 6.19 kB
JavaScript
;
/*
Copyright (c) 2025 Bernier LLC
This file is licensed to the client under a limited-use license.
The client may use and modify this code *only within the scope of the project it was delivered for*.
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSystemLogger = createSystemLogger;
exports.logSystem = logSystem;
exports.logError = logError;
exports.logWarn = logWarn;
exports.logInfo = logInfo;
exports.logDebug = logDebug;
exports.logSystemEntry = logSystemEntry;
const winston_1 = __importDefault(require("winston"));
const winston_daily_rotate_file_1 = __importDefault(require("winston-daily-rotate-file"));
const REQUIRED_ENV_VARS = ['LOG_LEVEL', 'NODE_ENV'];
function areRequiredEnvVarsPresent() {
return REQUIRED_ENV_VARS.every(envVar => !!process.env[envVar]);
}
/**
* Creates a Winston logger configured for system logging
* @param config Configuration options for the system logger
* @returns Configured Winston logger instance
*/
function createSystemLogger(config = {}) {
// Fail hard if used in a browser context
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
throw new Error('[@bernierllc/logging] System logger cannot be used in the browser. This logger is server-only and must only be instantiated in API or server-side code.');
}
if (!areRequiredEnvVarsPresent()) {
// No-op logger if required env vars are missing
return {
log: () => { },
error: () => { },
warn: () => { },
info: () => { },
debug: () => { },
add: () => { },
};
}
const isProduction = process.env.NODE_ENV === 'production';
const { level = process.env.LOG_LEVEL || 'info', format = 'combined', transports = [], defaultMeta = { service: 'system-log' }, enableConsole = !isProduction, // Disable console in production by default
enableFile = isProduction, // Enable file logging in production by default
filePath = './logs/system.log', enableSentry = false, sentryDsn,
// Log rotation defaults
maxSize = '10m', maxFiles = '5', datePattern = 'YYYY-MM-DD', zippedArchive = true } = config;
const loggerTransports = [];
// Add console transport if enabled
if (enableConsole) {
loggerTransports.push(new winston_1.default.transports.Console({
level: 'debug',
format: winston_1.default.format.combine(winston_1.default.format.colorize(), winston_1.default.format.timestamp(), winston_1.default.format.printf(({ timestamp, level, message, ...meta }) => {
return `${timestamp} [${level}]: ${message} ${Object.keys(meta).length ? JSON.stringify(meta, null, 2) : ''}`;
}))
}));
}
// Add file transport with rotation if enabled
if (enableFile) {
const fileTransport = new winston_daily_rotate_file_1.default({
filename: filePath.replace('.log', '-%DATE%.log'),
datePattern,
maxSize,
maxFiles,
zippedArchive,
level: 'info',
format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.json())
});
loggerTransports.push(fileTransport);
}
// Add Sentry transport if enabled
if (enableSentry && sentryDsn) {
try {
// Note: This would require winston-sentry-log or similar
// For now, we'll log to console as fallback
console.warn('Sentry transport not implemented, logging to console instead');
}
catch (error) {
console.warn('Failed to create Sentry transport');
}
}
// Add custom transports
loggerTransports.push(...transports);
// If no transports configured, add default console transport
if (loggerTransports.length === 0) {
loggerTransports.push(new winston_1.default.transports.Console({
level: 'debug',
format: winston_1.default.format.combine(winston_1.default.format.colorize(), winston_1.default.format.simple())
}));
}
const logger = winston_1.default.createLogger({
level,
format: winston_1.default.format.combine(winston_1.default.format.timestamp(), winston_1.default.format.errors({ stack: true }), winston_1.default.format.json()),
defaultMeta,
transports: loggerTransports
});
return logger;
}
/**
* Logs a system entry with proper formatting
* @param logger Winston logger instance
* @param entry System log entry data
*/
function logSystem(logger, entry) {
const systemEntry = {
...entry,
timestamp: entry.timestamp || new Date().toISOString(),
environment: process.env.NODE_ENV || 'development'
};
const { level, message, error, metadata, ...otherMeta } = systemEntry;
if (error) {
logger.log(level, message, { error: error.message, stack: error.stack, ...metadata, ...otherMeta });
}
else {
logger.log(level, message, { ...metadata, ...otherMeta });
}
}
/**
* Convenience functions for different log levels
*/
function logError(logger, message, error, metadata) {
logSystem(logger, { level: 'error', message, error, metadata });
}
function logWarn(logger, message, metadata) {
logSystem(logger, { level: 'warn', message, metadata });
}
function logInfo(logger, message, metadata) {
logSystem(logger, { level: 'info', message, metadata });
}
function logDebug(logger, message, metadata) {
logSystem(logger, { level: 'debug', message, metadata });
}
/**
* Convenience function to create and log system entry in one call
* @param entry System log entry data
* @param config Optional logger configuration
*/
function logSystemEntry(entry, config) {
const logger = createSystemLogger(config);
logSystem(logger, entry);
}
//# sourceMappingURL=systemLogger.js.map