WIP! A BB-style forum, on the ATmosphere! We're still working... we'll be back soon when we have something to show off!
node typescript hono htmx atproto
at main 61 lines 1.8 kB view raw
1import type { MiddlewareHandler } from "hono"; 2import { createMiddleware } from "hono/factory"; 3import type { Logger } from "./types.js"; 4 5/** 6 * Hono middleware that logs structured HTTP request/response data. 7 * 8 * Replaces Hono's built-in `logger()` middleware with OpenTelemetry-backed 9 * structured logging. Each request gets a child logger with request context 10 * that is available to downstream handlers via `c.get("logger")`. 11 * 12 * Log output: 13 * - Incoming request: method, path (at debug level) 14 * - Completed response: method, path, status, duration_ms 15 * (info for 2xx, warn for 4xx, error for 5xx — including errors handled by onError) 16 * 17 * @example 18 * ```ts 19 * import { createLogger } from "@atbb/logger"; 20 * import { requestLogger } from "@atbb/logger/middleware"; 21 * 22 * const logger = createLogger({ service: "atbb-appview" }); 23 * app.use("*", requestLogger(logger)); 24 * 25 * // In route handlers: 26 * app.get("/api/forum", (c) => { 27 * const log = c.get("logger"); 28 * log.info("Fetching forum metadata"); 29 * // ... 30 * }); 31 * ``` 32 */ 33export function requestLogger(logger: Logger): MiddlewareHandler { 34 return createMiddleware(async (c, next) => { 35 const start = performance.now(); 36 const method = c.req.method; 37 const path = c.req.path; 38 39 // Create a child logger scoped to this request 40 const reqLogger = logger.child({ 41 method, 42 path, 43 }); 44 45 // Make the logger available to downstream handlers 46 c.set("logger", reqLogger); 47 48 reqLogger.debug("Request received"); 49 50 await next(); 51 52 const duration = Math.round(performance.now() - start); 53 const status = c.res.status; 54 const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info"; 55 56 reqLogger[level]("Request completed", { 57 status, 58 duration_ms: duration, 59 }); 60 }); 61}