Files
MixedAssets/server/logger.js

38 lines
1.7 KiB
JavaScript

const path = require('path');
const fs = require('fs');
const winston = require('winston');
const moment = require('moment');
// Application/event logger (distinct from the DB audit trail, which records user data changes). This
// captures operational events — HTTP requests, and outbound integration activity (SMTP, webhook, Teams,
// ServiceNow, Workday) — as JSON lines in data/logs/app.log (size-rotated), readable by the Application
// Logs admin screen. A console transport keeps a readable line on stdout for local development.
const DATA_DIR = process.env.DEPRECORE_DATA_DIR || path.join(process.cwd(), 'data');
const LOG_DIR = path.join(DATA_DIR, 'logs');
fs.mkdirSync(LOG_DIR, { recursive: true });
const LOG_FILE = path.join(LOG_DIR, 'app.log');
const logger = winston.createLogger({
level: process.env.DEPRECORE_LOG_LEVEL || 'info',
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
transports: [
new winston.transports.File({ filename: LOG_FILE, maxsize: 5 * 1024 * 1024, maxFiles: 5, tailable: true }),
new winston.transports.Console({
format: winston.format.printf((info) => `${moment().format()} [${info.category || 'system'}] ${info.level}: ${info.message}`)
})
]
});
// Structured event logger. `category` groups the event (http | smtp | webhook | teams | servicenow |
// workday | system); `meta` is arbitrary structured detail. Never throws — logging must not break a flow.
function logEvent(category, message, meta = {}, level = 'info') {
try {
logger.log({ level, category: category || 'system', message, ...meta });
} catch {
// swallow — a logging failure should never affect the request it describes
}
}
module.exports = { logger, logEvent, LOG_FILE, LOG_DIR };