Bier.RequestLog (bier v0.1.0)

Copy Markdown View Source

Access-log formatting and the per-request SQL accumulator behind log-level and log-query (#28), mirroring PostgREST v14.12 Logger.hs.

should_log?/2 is upstream's shouldLogResponse: the configured level picks which responses get logged by status — crit none, error (the default) only ≥ 500, warn ≥ 400, info/debug everything.

access_line/3 renders the Apache-combined line PostgREST's WAI middleware emits (pinned by upstream's test_io.py log tests):

- - <role> [<ts>] "GET /path HTTP/1.1" <status> <bytes> "<referer>" "<user-agent>"

Host and ident are literal dashes; the user field is the resolved request role (including the anonymous role) or - when the request failed before role resolution. Timestamps are UTC (+0000) — PostgREST stamps the server's local zone, but Bier does not assume zone data is loadable.

The accumulator collects the SQL a request executes (armed per request by Bier.Plugs.Observability only when log-query is on, so the hot path pays nothing otherwise). It is process-scoped like Bier.ServerTiming: the plug and the query sites run in the same request process, and re-arming clears leftovers from a previous request on a keep-alive connection.

Summary

Functions

Render the Apache-combined access line for a sent response.

Arm (or disarm) SQL collection for the current request process, clearing any previous request's leftovers.

Return the recorded SQL in execution order and clear the accumulator.

Snapshot the accumulator for hand-off to another process (the cancellation task boundary, like Bier.ServerTiming.export/0). nil means disarmed.

Record an executed SQL statement. No-op unless the process is armed.

Adopt a snapshot produced by export/0 in the current process.

PostgREST Logger.hs shouldLogResponse: does status log at level?

Functions

access_line(conn, role, now)

@spec access_line(Plug.Conn.t(), String.t() | nil, DateTime.t()) :: String.t()

Render the Apache-combined access line for a sent response.

arm(bool)

@spec arm(boolean()) :: :ok

Arm (or disarm) SQL collection for the current request process, clearing any previous request's leftovers.

drain()

@spec drain() :: [String.t()]

Return the recorded SQL in execution order and clear the accumulator.

export()

@spec export() :: [String.t()] | nil

Snapshot the accumulator for hand-off to another process (the cancellation task boundary, like Bier.ServerTiming.export/0). nil means disarmed.

record(sql)

@spec record(String.t()) :: :ok

Record an executed SQL statement. No-op unless the process is armed.

restore(acc)

@spec restore([String.t()] | nil) :: :ok

Adopt a snapshot produced by export/0 in the current process.

should_log?(level, status)

@spec should_log?(:crit | :error | :warn | :info | :debug, integer() | nil) ::
  boolean()

PostgREST Logger.hs shouldLogResponse: does status log at level?