# Request logging captures method, path, status, and duration

- **Pattern:** `ab-002305` (`saas-logging.app-logging.request-logging`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002305
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002305)

## Why it matters

NIST AU-2 requires logging of events sufficient to support incident investigation; PCI-DSS Req 10.2 specifically mandates logging of all access to audit trails and system components, including HTTP method, status, and timing. Without request-level logs capturing method, path, status code, and duration, you cannot answer the most basic production questions: which endpoints are returning 500s, which are slow, and whether a latency spike started before or after a deploy. OWASP A09 identifies the absence of request logging as a direct enabler of undetected attacks — repeated 401s, scan patterns, and error spikes are invisible without a request log stream. Application-level logs that capture only business logic events are insufficient.

## Severity rationale

High because missing request logs make it impossible to detect error spikes, latency regressions, or attack patterns in production — the entire incident detection foundation is absent.

## Remediation

Add request logging at the middleware layer so every API call is recorded with method, path, status, and duration — regardless of whether individual handlers log anything.

For Next.js App Router, add to `middleware.ts`:
```ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(req: NextRequest) {
  const start = Date.now()
  const res = NextResponse.next()
  // Use a Vercel log drain or edge logger here in production
  console.log(JSON.stringify({
    method: req.method,
    path: req.nextUrl.pathname,
    status: res.status,
    duration: Date.now() - start
  }))
  return res
}
```

For Express or Fastify, use `morgan` or `fastify.addHook('onResponse', ...)`. If you're on Vercel and already using a log drain (Better Stack, Axiom), request logs are captured automatically from stdout — just ensure your handlers emit them.

## Detection

- **ID:** `request-logging`
- **Severity:** `high`
- **What to look for:** Enumerate all relevant files and Check middleware and API route handlers for request-level logging. Look for logging that captures at minimum: HTTP method, request path (without query strings containing tokens), HTTP status code, and response duration (elapsed time in milliseconds). Check for middleware-level request logging (`middleware.ts`, Express/Fastify middleware, Next.js instrumentation hooks in `instrumentation.ts`), or per-route logging in handlers.
- **Pass criteria:** At least 1 conforming pattern must exist. Request logging is present that records at minimum method, path, status code, and duration for API requests. The logging may be in middleware, a shared handler wrapper, or a platform-level integration (e.g., Vercel request logging, Axiom Vercel integration). Logging only a subset (e.g., method+path but no status or duration) does not pass. Report the count of conforming instances found even on pass.
- **Fail criteria:** No request logging found — API handlers log individual operations but no middleware or wrapper captures the HTTP request envelope (method, path, status, duration).
- **Skip (N/A) when:** Project has no server-side API routes or handlers. Static-site only.
- **Detail on fail:** Describe what's missing. Example: `"No request logging middleware found; API route handlers log business logic but not HTTP method, status code, or request duration"` or `"Middleware exists but only logs path — status code and duration not captured"`
- **Remediation:** Request-level logging is the foundation of production diagnostics. Without it, you cannot answer "what requests are failing?" or "which endpoints are slow?"

  For Next.js, create or update `instrumentation.ts` (App Router):
  ```ts
  export async function register() {
    if (process.env.NEXT_RUNTIME === 'nodejs') {
      const { default: logger } = await import('./lib/logger')
      // Wrap fetch or use middleware for request logging
    }
  }
  ```

  Or add to `middleware.ts`:
  ```ts
  import { NextResponse } from 'next/server'
  import type { NextRequest } from 'next/server'

  export function middleware(req: NextRequest) {
    const start = Date.now()
    const res = NextResponse.next()
    // Log after response — use a response wrapper or edge logger
    console.log(JSON.stringify({
      method: req.method,
      path: req.nextUrl.pathname,
      duration: Date.now() - start
    }))
    return res
  }
  ```

  For Express/Fastify, use `morgan` or the built-in `fastify.addHook('onResponse', ...)` hook.

## External references

- cwe CWE-778
- owasp A09
- nist AU-2
- pci-dss Req 10.2

Taxons: observability

HTML version: https://auditbuffet.com/patterns/ab-002305
