feat: add safe logging helper
This commit is contained in:
+61
-1
@@ -1 +1,61 @@
|
||||
// Safe logging utility (stderr only).
|
||||
// Safe logging utility (stderr only, JSON Lines).
|
||||
|
||||
import { redact } from './redact.js';
|
||||
|
||||
const LEVELS = { silent: 0, info: 10, warn: 20, error: 30 };
|
||||
|
||||
const SECRET_KEY_PATTERN = /(api[_-]?key|token|secret|password)/i;
|
||||
|
||||
function sanitizeMetadata(meta) {
|
||||
if (!meta) return {};
|
||||
|
||||
const filtered = {};
|
||||
for (const [key, value] of Object.entries(meta)) {
|
||||
if (typeof value === 'string' && SECRET_KEY_PATTERN.test(key.toLowerCase())) {
|
||||
filtered[key] = '[REDACTED]';
|
||||
} else if (typeof value === 'string' && /^Bearer\s+/i.test(value)) {
|
||||
// Preserve "Bearer " prefix, redact the token portion
|
||||
const cleaned = value.replace(/(Bearer\s+).+/, '$1[REDACTED]');
|
||||
filtered[key] = cleaned;
|
||||
} else {
|
||||
filtered[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
const jsonStr = JSON.stringify(filtered);
|
||||
const redactedStr = redact(jsonStr);
|
||||
|
||||
try {
|
||||
return JSON.parse(redactedStr);
|
||||
} catch {
|
||||
return filtered;
|
||||
}
|
||||
}
|
||||
|
||||
export function createLogger(level) {
|
||||
if (!(level in LEVELS)) {
|
||||
throw new Error(`Invalid log level: ${level}`);
|
||||
}
|
||||
|
||||
const currentLevel = LEVELS[level];
|
||||
|
||||
function write(eventLevel, message, metadata) {
|
||||
if (LEVELS[eventLevel] < currentLevel && currentLevel !== LEVELS.silent) return;
|
||||
if (currentLevel === LEVELS.silent) return;
|
||||
|
||||
const meta = sanitizeMetadata(metadata);
|
||||
const entry = JSON.stringify({
|
||||
level: eventLevel,
|
||||
ts: new Date().toISOString(),
|
||||
msg: message,
|
||||
meta,
|
||||
});
|
||||
process.stderr.write(entry + '\n');
|
||||
}
|
||||
|
||||
return {
|
||||
info: (message, metadata) => write('info', message, metadata),
|
||||
warn: (message, metadata) => write('warn', message, metadata),
|
||||
error: (message, metadata) => write('error', message, metadata),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user