AnnouncementsIntroducing Arkoren

    Menu

    Request Logging

    Record failed requests with the observed response status and optional trace correlation.

    What's on this page
    1. Log returned handler errors and observed 5xx responses without logging every request.
    2. Place tracing, request logging, and recovery so failures retain trace correlation.
    3. Interpret observed statuses, raw error exposure, and connection-hijack limits.
    On this page

    When a request fails, requestlog records its method, concrete path, observed status, and returned error. It is failure logging, not an access log: a handler error produces a record at any status, and an observed 5xx produces a record even without a returned error. Other successful responses and directly written 4xx responses produce none.

    Failure Records

    The path and raw error can contain personal identifiers, secrets, or native diagnostics. Choose log access, retention, and any application-owned redaction before enabling this middleware. If your telemetry driver exports logs, those same fields can leave the process; span field exclusions do not protect them. See Logs.

    With an existing application app and router r, import requestlog from arkoren.dev/core/http/middleware/requestlog and select the application’s logger before registering routes:

    r.Use(requestlog.Middleware(func(log *requestlog.Builder) {
    	log.Logger(app.Logger())
    }))

    If a report handler returns an error rendered as HTTP 503, its record contains these fields (timestamps and other logger attributes are omitted):

    {
      "level": "ERROR",
      "msg": "request failed",
      "method": "POST",
      "path": "/reports",
      "status": 503,
      "error": "503 Service Unavailable"
    }

    The actual error string depends on the returned error. Any *slog.Logger works. If Logger is nil or omitted, the middleware resolves slog.Default() per request, so a later default change takes effect. Selecting a logger does not itself enable telemetry or provide trace correlation.

    Middleware Order

    For trace IDs and recovered panics, use this alternative registration with the application’s configured telemetry. Import router from arkoren.dev/core/http/router:

    r.Use(
    	app.Telemetry().Middleware(),
    	requestlog.Middleware(func(log *requestlog.Builder) {
    		log.Logger(app.Logger())
    	}),
    	router.Recover(),
    )

    Telemetry runs first so logging receives the request’s span context. The application logger’s telemetry wrapper adds trace_id and span_id when that identity is valid. An unrelated plain slog handler does not acquire correlation just because tracing middleware ran.

    Recovery runs inside logging so recovered panics become returned errors the logger can observe. Do not register both setup variants on the same route stack: choose one, or you can produce duplicate failure records.

    Response Boundaries

    Logging runs after the router completes response handling, including rendering returned errors. The observed status is what passed through the response writer, not evidence the client received those bytes. The middleware relies on Arkoren router response hooks; exercise it through the router rather than invoking an isolated wrapped handler.

    A returned validation error rendered as 422 produces an error log, while its server span is not marked failed: HTTP server spans classify 5xx responses as errors. These are intentionally different signals, not contradictory outcomes.

    A successful connection hijack is not a failure. If the handler returns an error after taking ownership of the connection, it is still logged. Status 0 means no final HTTP status passed through the writer; it is neither an inferred 500 nor a status sent to the client. Direct connection writes are outside the HTTP response hooks.

    For configuration declarations, see the requestlog API reference.

    Open a bulk documentation archive?

    This file contains every guide in its scope, not API declarations. Loading it all into an agent can exhaust its context window and increase processing time and cost. For coding tasks, start with the index and read only the relevant pages.

    Use the full archive for offline indexing, bulk processing, or deliberate large-context use.

    Browse the index instead
    Open archive