Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 545x 545x 545x 545x 541x 540x 3x 1x 2x 545x 540x 92x 302x 540x 5x 5x 545x 545x 5x 5x 3x 40x 304x 1x 92x 148x | // Structured logger for the Hono API. The single allowed sink for route-side
// observability — Biome blocks raw `console.*` under `src/routes/**`.
//
// API: `logger.info(...args)`, `logger.warn(...args)`, `logger.error(...args)`
// mirrors `console.log/warn/error` so route call sites can migrate by name.
//
// - In dev/test, prints `[level] <args…>` to the console.
// - In preview/production (Cloudflare Workers), emits a single JSON line per
// call: `{"level":"...","message":"...","extra":[...]}` so Workers logpush
// can ingest cleanly. The first string arg becomes `message`; remaining
// args are stashed in `extra` (Errors serialized to plain objects).
//
// The logger never throws. If the environment is unreadable, it falls back to
// dev formatting (verbose but harmless).
type LogLevel = "info" | "warn" | "error";
function isDevEnv(): boolean {
try {
// biome-ignore lint/suspicious/noExplicitAny: globalThis.process is optional on Workers
const env = (globalThis as any).process?.env;
Iif (!env) return true;
if (env.NODE_ENV === "production") return false;
if (env.ENVIRONMENT === "preview" || env.ENVIRONMENT === "production") return false;
return true;
} catch {
return true;
}
}
function serialize(value: unknown): unknown {
if (value instanceof Error) {
return { name: value.name, message: value.message, stack: value.stack };
}
return value;
}
// The Biome `noConsole` rule is scoped via overrides to `src/routes/**` only,
// so the raw `console.*` calls below are not flagged here. No suppression
// comments are needed (and adding them produces a `suppressions/unused`
// error in CI).
function emit(level: LogLevel, args: unknown[]): void {
if (isDevEnv()) {
if (level === "error") console.error(...args);
else if (level === "warn") console.warn(...args);
else console.log(...args);
return;
}
const [first, ...rest] = args;
const message = typeof first === "string" ? first : JSON.stringify(serialize(first));
const entry: Record<string, unknown> = { level, message };
if (rest.length > 0) entry.extra = rest.map(serialize);
const line = JSON.stringify(entry);
if (level === "error") console.error(lineI);
else if (level === "warn") console.warn(line);
else console.log(line);
}
export const logger = {
info: (...args: unknown[]) => emit("info", args),
log: (...args: unknown[]) => emit("info", args),
warn: (...args: unknown[]) => emit("warn", args),
error: (...args: unknown[]) => emit("error", args),
};
export type Logger = typeof logger;
|