// LogTape alternative: JSON lines + redaction sink wrapper. import { configure, getJsonLinesFormatter, getLogger, getStreamSink, type LogRecord, type Sink } from "@logtape/logtape"; import { redact, redactString } from "@spike/x"; const base = getStreamSink(Deno.stdout.writable, { formatter: getJsonLinesFormatter() }); const redacting = (inner: Sink): Sink => (r: LogRecord) => inner({ ...r, message: r.message.map((m: unknown) => (typeof m === "string" ? redactString(m) : redact(m))), rawMessage: typeof r.rawMessage === "string" ? redactString(r.rawMessage) : r.rawMessage, properties: redact(r.properties) as Record }); await configure({ sinks: { out: redacting(base) }, loggers: [{ category: ["umt"], lowestLevel: "info", sinks: ["out"] }, { category: ["logtape", "meta"], lowestLevel: "warning", sinks: ["out"] }] }); const log = getLogger(["umt", "worker"]); log.info("fetch {url}", { url: "https://x/rss?passkey=SECRET", token: "abc", n: 3 }); log.with({ runId: "r1", apiKey: "k" }).warn("child context"); await new Promise((r) => setTimeout(r, 100));