Files
peardata/server/utils/logger.js
T
Raven Scott 015d92a257
Release rolling / release (push) Has been cancelled
CI / test (push) Has been cancelled
first commit
2026-07-18 16:17:38 -04:00

57 lines
1.6 KiB
JavaScript

/**
* Tiny structured logger (JSON lines optional).
*/
const LEVELS = { debug: 10, info: 20, warn: 30, error: 40 }
const minLevel =
LEVELS[String(process.env.LOG_LEVEL || 'info').toLowerCase()] ?? LEVELS.info
function emit(level, scope, message, fields) {
if ((LEVELS[level] ?? 99) < minLevel) return
const line = {
ts: new Date().toISOString(),
level,
scope,
msg: message,
...(fields && typeof fields === 'object' ? fields : {}),
}
const text = process.env.LOG_JSON === '1' ? JSON.stringify(line) : formatPretty(line)
if (level === 'error') console.error(text)
else if (level === 'warn') console.warn(text)
else console.log(text)
}
function formatPretty(line) {
const extra = { ...line }
delete extra.ts
delete extra.level
delete extra.scope
delete extra.msg
const keys = Object.keys(extra)
const tail = keys.length ? ' ' + JSON.stringify(extra) : ''
return `${line.ts} [${line.level}] ${line.scope}: ${line.msg}${tail}`
}
function child(scope) {
return {
debug: (msg, fields) => emit('debug', scope, msg, fields),
info: (msg, fields) => emit('info', scope, msg, fields),
warn: (msg, fields) => emit('warn', scope, msg, fields),
error: (msg, fields) => emit('error', scope, msg, fields),
child: (sub) => child(`${scope}:${sub}`),
banner(fields = {}) {
const bar = '═'.repeat(56)
console.log(bar)
console.log(` ${fields.title || 'Pear App Server'}`)
for (const [k, v] of Object.entries(fields)) {
if (k === 'title') continue
console.log(` ${k}: ${v}`)
}
console.log(bar)
},
}
}
const logger = child('app')
export default logger