File
Blob: src/worker/middleware/request-logging.ts
| 1 | import { createMiddleware } from "hono/factory"; |
| 2 | |
| 3 | import type { AppEnv } from "@/worker/types"; |
| 4 | import { createLogger, errorContext } from "@/worker/util/logging"; |
| 5 | import { destinationHost, pathPrefix } from "@/worker/util/request-context"; |
| 6 | |
| 7 | const log = createLogger("request"); |
| 8 | |
| 9 | function overwriteHeader(value: string | undefined): string | null { |
| 10 | if (!value) return null; |
| 11 | return value.toUpperCase() === "F" ? "F" : "T"; |
| 12 | } |
| 13 | |
| 14 | export const requestLogging = () => |
| 15 | createMiddleware<AppEnv>(async (c, next) => { |
| 16 | const started = Date.now(); |
| 17 | const request = c.req.raw; |
| 18 | const url = new URL(c.req.url); |
| 19 | const base = { |
| 20 | requestId: c.get("requestId"), |
| 21 | method: c.req.method, |
| 22 | pathPrefix: pathPrefix(url.pathname), |
| 23 | hostLabel: c.get("hostInfo")?.hostLabel ?? null, |
| 24 | davDepth: request.headers.get("depth"), |
| 25 | davDestinationHost: destinationHost(request), |
| 26 | davOverwrite: overwriteHeader(c.req.header("overwrite")), |
| 27 | davIfPresent: request.headers.has("if"), |
| 28 | litmusHeader: c.req.header("x-litmus") ?? null, |
| 29 | }; |
| 30 | |
| 31 | try { |
| 32 | await next(); |
| 33 | log.info("request.complete", { |
| 34 | ...base, |
| 35 | status: c.res.status, |
| 36 | latencyMs: Date.now() - started, |
| 37 | errorCode: c.res.status >= 400 ? `http_${c.res.status}` : null, |
| 38 | }); |
| 39 | } catch (error) { |
| 40 | log.error("request.error", { |
| 41 | ...base, |
| 42 | status: 500, |
| 43 | latencyMs: Date.now() - started, |
| 44 | errorCode: "unhandled_exception", |
| 45 | ...errorContext(error), |
| 46 | }); |
| 47 | throw error; |
| 48 | } |
| 49 | }); |