// pino 10 on Deno: sync stdout, custom destination, formatters/hooks redaction, child loggers, pino.transport (worker_threads). import pino from "pino"; import { redact, redactString } from "@spike/x"; import { Writable } from "node:stream"; const opts: pino.LoggerOptions = { level: "info", formatters: { log: (obj) => redact(obj) as Record }, hooks: { logMethod(args, method) { return method.apply(this, args.map((a) => (typeof a === "string" ? redactString(a) : a)) as typeof args); }, }, }; const lines: string[] = []; const dest = new Writable({ write(chunk, _enc, cb) { lines.push(String(chunk)); cb(); } }); const log = pino(opts, dest); log.info({ token: "abc", url: "https://x/rss?passkey=SECRET&a=1", n: 1 }, "fetch https://x?api_key=K"); log.child({ component: "worker", password: "p" }).warn({ err: new Error("boom token=zzz") }, "child"); console.log("custom-dest:", lines.join("").trim()); pino(opts).info({ cookie: "c=1" }, "stdout default destination"); const t = pino.transport({ target: "pino/file", options: { destination: 1 } }); const lt = pino(opts, t); lt.info({ secret: "s" }, "via pino.transport (worker_threads)"); await new Promise((r) => setTimeout(r, 300)); t.end(); if (Deno.env.get("PRETTY")) { const pp = pino({ ...opts, transport: { target: "pino-pretty", options: { translateTime: "SYS:HH:MM:ss" } } }); pp.info({ token: "x" }, "via pino-pretty transport"); await new Promise((r) => setTimeout(r, 500)); }