/** * Structured stderr logger for the MCP server's informational output. * * **Why this exists.** The server writes ~90 informational stderr lines as * plain text (`obsidian-brain: `). Operators piping logs into log * aggregators (Datadog, Loki, Vector, journald with json-formatted ingest) * want one-JSON-object-per-line output so they can index on level, message, * and structured fields without regex-extracting them from prose. Gate the * structured mode on an env var so the default human-readable format is * preserved (no breaking change for users tailing the file by eye). * * **Why async writes (process.stderr.write).** Informational logs from * indexer / watcher / embedder paths fire well after preflight returns and * well before any crash. The race that v1.7.7 documents (async stderr buffer * vs process.exit) only matters for the crash-path sites in * `src/preflight.ts`, `src/global-handlers.ts`, and the writeSync fallback * in `src/server.ts:287`. Those sites stay on `fs.writeSync(2, …)` — this * module is explicitly NOT for them. * * **Why read env on every call.** Tests need to override * `OBSIDIAN_BRAIN_LOG_FORMAT` between describe blocks. Reading the env on * each invocation costs a single object-property lookup (env var access is * O(1) in Node) — well below the cost of the JSON.stringify or the * stderr.write itself. Production deployments set the var once at process * start, so the read is effectively constant for them too. * * **Output formats:** * - Default (env unset / empty): `obsidian-brain: \n` — * preserves the existing user-visible format. * - `OBSIDIAN_BRAIN_LOG_FORMAT=ndjson`: one JSON object per line, with * keys `ts` (ISO-8601 UTC timestamp), `level` (info|warn|error), * `msg` (the message string), plus any structured fields merged in. * `JSON.stringify` handles control-character escaping per the JSON * spec, so newlines / tabs / quotes in messages produce valid JSON. */ export type LogLevel = 'info' | 'warn' | 'error'; export interface Logger { info(message: string, fields?: Record): void; warn(message: string, fields?: Record): void; error(message: string, fields?: Record): void; } export declare const logger: Logger;