serve.admin.request_log.disable_for_health has no effect (admin prefix added after the request logger)
Describe the bug
serve.admin.request_log.disable_for_health: true does not suppress request logs for /admin/health/ready (or /admin/health/alive).
In cmd/daemon/serve.go, serveAdmin builds the exclusion list with the /admin prefix, but registers the reqlog middleware before httprouterx.AddAdminPrefixIfNotPresentNegroni:
adminLogger := reqlog.NewMiddlewareFromLogger(l, "admin#"+cfg.BaseURL.String())
if cfg.RequestLog.DisableHealth {
adminLogger.ExcludePaths(
httprouterx.AdminPrefix+healthx.AliveCheckPath,
httprouterx.AdminPrefix+healthx.ReadyCheckPath,
httprouterx.AdminPrefix+prometheusx.MetricsPrometheusPath,
)
}
n.UseFunc(semconv.Middleware)
n.Use(adminLogger)
n.UseFunc(httprouterx.AddAdminPrefixIfNotPresentNegroni) // prefix added AFTER reqlogreqlog.Middleware.ServeHTTP matches r.URL.Path against silencePaths, so at that point the path is still /health/ready and never matches /admin/health/ready.
The logged line nevertheless shows /admin/health/ready, because DefaultAfter re-evaluates WithRequest after the prefix has been added — which makes the mismatch hard to spot from the logs alone.
The public listener is unaffected (no prefix middleware), which is why serve.public.request_log.disable_for_health works as documented.
Reproducing the bug
- Run Kratos with
serve.admin.request_log.disable_for_health: true. curl http://<admin-host>:4434/health/readyrepeatedly.- Every request is logged at
infowithmsg="completed handling request".
Relevant log output
{"http_request":{"headers":{"user-agent":"ELB-HealthChecker/2.0"},"host":"10.0.0.1:4434","method":"GET","path":"/admin/health/ready","query":null},"http_response":{"status":200,"size":16,"text_status":"OK","took":1008988},"level":"info","msg":"completed handling request"}Expected behavior
Health probes against the admin listener are not logged when disable_for_health is true.
Environment
- Kratos v26.2.0, self-hosted via
oryd/kratos:v26.2.0 - Config:
serve.admin.request_log.disable_for_health: true,log.level: info
Impact
With an ALB target group health check plus a container HEALTHCHECK, both every 30s, health probes were ~99% of our request-log volume: ~60,500 of ~61,000 completed handling request lines over 7 days, ~240 MB/month of CloudWatch ingestion, against ~600 lines/week of real auth traffic.
Suggested fix
Either register AddAdminPrefixIfNotPresentNegroni before the reqlog middleware, or add both the prefixed and unprefixed health paths to the exclusion list.
Source: ory/kratos