Help us shape the future of Go! Take the 2026 Go Developer Survey

reqlog

package
v0.20.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package reqlog is Studio's server log of failed requests (UX-E-37, audit row D10): every request carries a request id — the client's X-Request-Id when it sent a well-formed one, else a generated one — echoed on the response; a refused ingest batch (a 4xx on /v1/) is one WARN line and every 5xx one ERROR line on slog.Default, each naming the request id, the status and the reason the handler answered with (Refuse; Cause when the body masks the real error). Studio's error bodies carry the id on a 5xx too, so a report from a user meets its line in studio.log. A handler panic is one ERROR line with the id; the panic goes on up to net/http.

Ingest refusals are rate-limited per (remote host, route, status, code), the route being its class — /v1/traces, /v1/logs, else /v1/*, so a scan of distinct /v1/<x> paths shares one key: the first in a minute is logged, the rest counted onto the next line (suppressed=n) — a misconfigured exporter retrying every second leaves one line a minute, never a flood. The limiter holds at most 1,024 keys: full, it drops the expired windows first — the refusals they had suppressed since their last line are carried onto the next line logged (suppressed_expired=n), never lost with them; when none has expired, a refusal under a new key is not logged until a window turns, and the next line logged carries the count (suppressed_overflow=n). Behind a reverse proxy every client arrives from the proxy's address, so they share one remote and one limit. 5xx lines are never limited.

The logger also counts the ingest batches (POSTs under /v1/) it saw accepted and refused, with the last refusal and its time (Ingest): /api/meta's ingest section.

Index

Constants

View Source
const Header = "X-Request-Id"

Header is the request id's header, read from the request and set on every response.

Variables

This section is empty.

Functions

func Cause

func Cause(ctx context.Context, msg string)

Cause records the real reason behind a refusal whose body masks it (a 5xx answered to a panel token names the operation, never the database's error text): the server log names msg, the body keeps what Refuse was given. A no-op outside Wrap.

func ID

func ID(ctx context.Context) string

ID is the request's id, "" outside Wrap.

func Refuse

func Refuse(ctx context.Context, code, msg string)

Refuse records why the request is answered with an error (the error body's code and message): the line Wrap logs names it. A no-op outside Wrap.

Types

type IngestCounts

type IngestCounts struct {
	Accepted  int64
	Refused   int64
	LastError string
	LastAt    time.Time
}

IngestCounts is what the logger saw of ingest (POSTs under /v1/): the batches answered 2xx, the batches refused (4xx and 5xx), and the last refusal — "<status> <code>: <reason>" — with its time (zero before the first).

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger is one server's request log: its rate limit's state and the ingest counters.

func New

func New() *Logger

New returns a request log.

func (*Logger) Ingest

func (l *Logger) Ingest() IngestCounts

Ingest returns the ingest counters so far: in memory, a restart starts them again from zero.

func (*Logger) Wrap

func (l *Logger) Wrap(next http.Handler) http.Handler

Wrap gives every request its id (on the context and the response's X-Request-Id) and logs, once it is answered, a 5xx at ERROR and a refused ingest batch (a 4xx under /v1/) at WARN. A handler panic is logged at ERROR with the id and panics on (http.ErrAbortHandler, net/http's deliberate abort, is not logged).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL