Media Gateway uses two complementary logging layers. They serve different purposes and neither replaces the other.
nginx owns public HTTP access and transport logging for the published Media Gateway route.
This layer is useful for:
The nginx access log is the primary request/access record. Media Gateway should not duplicate a second full access log for every successful request. Log retention/rotation for these files belongs to the host’s normal nginx/logrotate policy rather than Media Gateway.
Public-edge logging must not record secrets. In particular:
Authorization or provider credentials;The public media surface is intentionally path-based and requires no secret query parameter.
The reference media_gateway access format records the peer, method, classified
route (catalog, preview, original or denied), status, bytes, request/upstream timings
and request/connection limit outcomes. Routine limit events use notice, below
the warn error-log threshold; 429 remains visible in access logs. It omits
raw paths, asset IDs, query strings, Host, Referer, User-Agent and all credential
headers. Both the default-deny and media servers use this format and dedicated
access/error files. Behind an edge the peer may be the local tunnel; do not trust
caller-supplied forwarded chains as identity.
nginx error logging at warn retains proxy transport diagnostics and can include
caller-supplied request lines/queries. It is not a configurable access-log format:
query-safe access logging alone does not qualify future signed/query-token URLs.
Review error logs and every edge layer before introducing secrets in URLs; never
put provider credentials there. The only configured upstream is the gateway, so
actual provider/NAS paths and provider credentials are unavailable to nginx.
Attacker-supplied text in an error request line is not trusted provider metadata.
Do not enable debug/header logging. Check installed log permissions and host
rotation/retention, including inherited logging destinations, during qualification.
The Go process owns application/security/diagnostic logging that nginx cannot provide.
Use the Go standard library log/slog and write to stderr/stdout. Under the reference systemd deployment, journald owns persistence, indexing and rotation. The application does not create or rotate its own log files.
Log useful lifecycle and failure events such as:
Do not routinely log:
Known-private or malformed public requests are normal hostile/invalid Internet traffic and must not become an unbounded warning-log amplification path. Routine policy denials should normally remain quiet or low-verbosity; unexpected invariant/provider failures merit higher severity.
The service emits JSON slog records to stderr at INFO for starting,
configuration loaded, listening, stopping, and stopped. Startup metadata is
limited to build provenance and the validated loopback listener. It never dumps
configuration, roots, provider URLs or credential paths. Configuration errors use
the shared loader’s sanitized field/operation messages; bind/serve/shutdown errors
use fixed failure descriptions and cause a nonzero exit.
The public handler keeps successes and routine malformed/private/missing denials
quiet. Exceptional failures before headers emit one provider request failed
warning with the adapter’s fixed sanitized outcome. Failed body copies emit only
media stream failed; canceled public requests remain quiet. No request IDs,
asset IDs, provider paths, Range/If-Range values or body text are logged.
The catalog handler emits provider search failed with fixed provider failure
outcomes, mapping a search-endpoint HTTP 404 to unexpected provider status. It keeps
successes, invalid pagination, private/missing denials and cancellation quiet.
Catalog cursors and search results are never logged.
The standard HTTP server’s connection error logger is discarded because its free
text can include request-controlled data; lifecycle failures are reported separately
through slog. Streaming failures use http.ErrAbortHandler to terminate incomplete responses
without free-text panic logging. Preserve privacy and bounded diagnostic volume
when changing this behavior.
Conceptually:
Internet request
|
v
nginx
|-- access/error log: HTTP edge/transport facts
|
v
Media Gateway
|-- slog -> stderr -> journald: lifecycle, provider, policy/runtime diagnostics
|
v
private provider
This keeps the service small: no logging framework, log database, agent, or application-managed rotation is required.
Before production qualification, verify that:
journalctl -u media-gateway;