Files
dashback/src/util/errorLog.js
2026-10-08 03:43:28 +02:00

59 lines
2.0 KiB
JavaScript

import { appendFileSync, mkdirSync } from 'fs';
import { dirname, resolve } from 'path';
import { fileURLToPath } from 'url';
import { prettyJson } from '../util/prettyJson.js';
import { createLogger } from '../util/logger.js';
const log = createLogger('error-log');
const __dirname = dirname(fileURLToPath(import.meta.url));
const LOG_DIR = process.env.ERROR_LOG_DIR || resolve(__dirname, '../../logs/errors');
const LOG_PREFIX = 'error-';
let dirEnsured = false;
function ensureLogDir() {
if (dirEnsured) return;
mkdirSync(LOG_DIR, { recursive: true });
dirEnsured = true;
}
/**
* Writes a plain-text error log file (no ANSI colors) to the error log
* directory and returns the file path. Never throws.
* @param {string} label Short description, e.g. "POST /api/delivery 500"
* @param {Record<string, unknown>} sections Named sections (request, body, response, error…)
* @returns {string | null} Path of the log file, or null on failure
*/
export function writeErrorLog(label, sections) {
try {
ensureLogDir();
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
const safeLabel = label
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-+|-+$/g, '')
.slice(0, 40);
const filePath = resolve(LOG_DIR, `${LOG_PREFIX}${stamp}-${safeLabel}.log`);
const divider = '='.repeat(80);
const parts = [
`Timestamp: ${new Date().toISOString()}`,
`Label: ${label}`,
divider,
];
for (const [name, value] of Object.entries(sections)) {
parts.push(`--- ${name} ${'-'.repeat(Math.max(0, 74 - name.length))}`);
parts.push(prettyJson(value, { colors: false }));
}
appendFileSync(filePath, `${parts.join('\n')}\n`);
log.info(`Wrote ${filePath}`);
return filePath;
} catch (err) {
log.error('Failed to write error log:', err.message);
return null;
}
}