Files
craftdock/src/logger.js
T
Lucas RayanandClaude Sonnet 5.5 640e52c0c9 Initial commit: CraftDock as of 2026-11-01
The previous GitHub history was lost with the account (the local .git was missing
its refs and most objects), so this repository starts from the existing code.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 22:44:39 -03:00

78 lines
2.3 KiB
JavaScript

// Lightweight structured logger. No dependencies — writes one record per line
// to a stream (stdout by default). Level is controlled by LOG_LEVEL
// (error < warn < info < debug); anything above the threshold is dropped.
// Format is controlled by LOG_FORMAT (json | text, default: text).
const LEVELS = { error: 0, warn: 1, info: 2, debug: 3 };
function serializeMeta(meta) {
if (meta == null) return undefined;
if (meta instanceof Error) {
return { error: meta.message, stack: meta.stack, cause: meta.cause };
}
if (typeof meta !== 'object') {
return { value: meta };
}
const out = {};
for (const [key, value] of Object.entries(meta)) {
if (value instanceof Error) {
out[key] = { error: value.message, stack: value.stack, cause: value.cause };
} else {
out[key] = value;
}
}
return out;
}
function formatTextRecord(record) {
const lvlStr = record.level.toUpperCase().padEnd(5);
const metaStr = record.meta ? ` ${JSON.stringify(record.meta)}` : '';
return `[${record.ts}] [${lvlStr}] [${record.component}] ${record.msg}${metaStr}\n`;
}
export function createLogger(component, {
level = process.env.LOG_LEVEL || 'info',
format = process.env.LOG_FORMAT || 'text',
stream = process.stdout,
} = {}) {
const threshold = LEVELS[level] ?? LEVELS.info;
const isJson = format === 'json';
function log(lvl, msg, meta) {
if (LEVELS[lvl] > threshold) return;
const record = {
ts: new Date().toISOString(),
level: lvl,
component,
msg,
};
const m = serializeMeta(meta);
if (m !== undefined) record.meta = m;
if (isJson) {
stream.write(JSON.stringify(record) + '\n');
} else {
stream.write(formatTextRecord(record));
}
}
return {
error: (msg, meta) => log('error', msg, meta),
warn: (msg, meta) => log('warn', msg, meta),
info: (msg, meta) => log('info', msg, meta),
debug: (msg, meta) => log('debug', msg, meta),
time: (label, lvl = 'info') => {
const start = Date.now();
return (meta = {}) => {
const durationMs = Date.now() - start;
log(lvl, `${label} took ${durationMs}ms`, { ...meta, durationMs });
};
},
child: (sub) => createLogger(`${component}:${sub}`, { level, format, stream }),
};
}
// Default application logger.
export const logger = createLogger('craftdock');