feat(surf): serve startup summary, shutdown report and http request log
- serve prints a startup summary on a terminal (version, environment, URL, admin, database host and name, pending migrations, plugins, drivers) and logs it as a 'startup summary' record plus 'listening on <addr>' - on SIGINT/SIGTERM serve drains, prints and logs a shutdown report and returns nil (exit 0), or the drain errors (exit 1) - the request log is on by default under diary component http with request_id; the route pattern, never the path, is logged - lagoon.PendingMigrations, conga.Worker.Stats, diary.HideOnTTY, bonfire.IsTerminal and bonfire.Details back the summary and report
This commit is contained in:
@@ -146,14 +146,7 @@ Redaction is a safety net for mistakes, not a way to log secrets on purpose. Log
|
||||
|
||||
## Request log
|
||||
|
||||
The router can log every request. It is off by default; turn it on with the `http.access_log` key (environment `SUMMER_HTTP__ACCESS_LOG=true`):
|
||||
|
||||
```yaml
|
||||
# config/http.yaml
|
||||
access_log: true
|
||||
```
|
||||
|
||||
Each request then writes one Info record with the message `http request` once it has been served:
|
||||
The router logs every request. Each request writes one Info record with the message `http request` from the component `http` once it has been served:
|
||||
|
||||
| Attribute | Value |
|
||||
|-----------|-------|
|
||||
@@ -161,9 +154,25 @@ Each request then writes one Info record with the message `http request` once it
|
||||
| `pattern` | The matched route, method and path pattern, for example `GET /posts/{id}`. Empty when no route matched. |
|
||||
| `status` | The response status; a handler that writes without setting one counts as 200. A 5xx is logged as 499 (client closed request) only when the client had already gone away when the status was written and the handler did not panic: the error came from the cancellation, and no client received it. A 5xx written before the client went away keeps its status, and a recovered panic is always 500, so a search for 5xx records finds every real server error. |
|
||||
| `duration_ms` | Time spent serving the request, in whole milliseconds. |
|
||||
| `request_id` | The `X-Request-Id` request header, trimmed and cut to 128 bytes; absent when the header is empty. Set it in your reverse proxy to follow one request across the proxy's and the application's logs. |
|
||||
| `client_gone` | `true` when the client went away before the request was served (its context ended with `context.Canceled`); absent otherwise. |
|
||||
|
||||
The record never carries the URL path, the query string, request or response headers or the client address, because tokens often travel in paths and query strings. That holds for a request that reached no route too: a token route requested with another method gets a 405 from the router, and its trailing-slash variant a 404, before any route handler runs, so the path would carry the token. It goes to the published `*slog.Logger` or `slog.Default`, so the redacting handler still applies. Grep for the empty `pattern` to find requests that reached no route; the client's own log (a browser, a proxy) shows which path it asked for.
|
||||
The record carries the route pattern, never the URL path, the query string, request or response headers or the client address, because tokens travel in paths and query strings: share and invitation links carry them in the path. That holds for a request that reached no route too: a token route requested with another method gets a 405 from the router, and its trailing-slash variant a 404, before any route handler runs, so the path would carry the token. Grep for the empty `pattern` to find requests that reached no route; the client's own log (a browser, a proxy) shows which path it asked for.
|
||||
|
||||
The log is on by default, at Info, so the console shows it and the daily files keep what their level lets through. Silence it with the component level, or turn it off with `http.access_log` (environment `SUMMER_HTTP__ACCESS_LOG=false`):
|
||||
|
||||
```yaml
|
||||
# config/log.yaml
|
||||
components:
|
||||
http: warn
|
||||
```
|
||||
|
||||
```yaml
|
||||
# config/http.yaml
|
||||
access_log: false
|
||||
```
|
||||
|
||||
It goes to the published `*slog.Logger` when a plugin publishes one, else to the `http` component logger, so the redacting handler applies on every channel.
|
||||
|
||||
## Panics
|
||||
|
||||
|
||||
Reference in New Issue
Block a user