72 lines
1.8 KiB
JavaScript
72 lines
1.8 KiB
JavaScript
const path = require('path');
|
|
const { logsDir } = require('./paths');
|
|
const { appendJsonLine } = require('./fs');
|
|
|
|
const SECRET_PATTERNS = ['token', 'secret', 'password', 'authorization'];
|
|
|
|
function sanitizeValue(value) {
|
|
if (Array.isArray(value)) {
|
|
return value.map(sanitizeValue);
|
|
}
|
|
|
|
if (!value || typeof value !== 'object') {
|
|
return value;
|
|
}
|
|
|
|
return Object.fromEntries(
|
|
Object.entries(value).map(([key, entryValue]) => {
|
|
const lower = key.toLowerCase();
|
|
|
|
if (SECRET_PATTERNS.some((pattern) => lower.includes(pattern))) {
|
|
return [key, '[redacted]'];
|
|
}
|
|
|
|
return [key, sanitizeValue(entryValue)];
|
|
})
|
|
);
|
|
}
|
|
|
|
function dayString(timestamp) {
|
|
return timestamp.slice(0, 10);
|
|
}
|
|
|
|
async function log(entry) {
|
|
const timestamp = new Date().toISOString();
|
|
const logEntry = {
|
|
timestamp,
|
|
level: entry.level || 'info',
|
|
service: entry.service,
|
|
node_id: entry.node_id || null,
|
|
tenant_id: entry.tenant_id || null,
|
|
request_id: entry.request_id || null,
|
|
correlation_id: entry.correlation_id || null,
|
|
action: entry.action || 'unknown',
|
|
result: entry.result || 'unknown',
|
|
metadata: sanitizeValue(entry.metadata || {}),
|
|
};
|
|
|
|
await appendJsonLine(path.join(logsDir, dayString(timestamp), `${logEntry.service}.ndjson`), logEntry);
|
|
process.stdout.write(`${JSON.stringify(logEntry)}\n`);
|
|
return logEntry;
|
|
}
|
|
|
|
function createLogger(baseFields) {
|
|
return {
|
|
info(action, result, metadata) {
|
|
return log({ ...baseFields, level: 'info', action, result, metadata });
|
|
},
|
|
warn(action, result, metadata) {
|
|
return log({ ...baseFields, level: 'warn', action, result, metadata });
|
|
},
|
|
error(action, result, metadata) {
|
|
return log({ ...baseFields, level: 'error', action, result, metadata });
|
|
},
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
log,
|
|
createLogger,
|
|
};
|
|
|