From e026cbf4e9ce35beebcb23e1d1922c0e2dffaad1 Mon Sep 17 00:00:00 2001 From: chaoshou <1813591343@qq.com> Date: Tue, 8 Sep 2026 18:41:38 +0800 Subject: [PATCH] fix(api): skip access logging for health probes --- internal/api/server_routes.go | 4 ++-- internal/api/server_test.go | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/internal/api/server_routes.go b/internal/api/server_routes.go index 1c6ce6d6a..7a350a5b9 100644 --- a/internal/api/server_routes.go +++ b/internal/api/server_routes.go @@ -48,8 +48,8 @@ func (s *Server) setupRoutes() { c.JSON(http.StatusOK, gin.H{"status": "ok"}) } - s.engine.GET("/healthz", healthzHandler) - s.engine.HEAD("/healthz", healthzHandler) + s.engine.GET("/healthz", logging.SkipGinRequestLogging, healthzHandler) + s.engine.HEAD("/healthz", logging.SkipGinRequestLogging, healthzHandler) s.engine.GET("/management.html", s.serveManagementControlPanel) openaiHandlers := openai.NewOpenAIAPIHandler(s.handlers) diff --git a/internal/api/server_test.go b/internal/api/server_test.go index e7512d89e..1a7d8b3df 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -32,6 +32,8 @@ import ( coreusage "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/usage" sdkconfig "github.com/router-for-me/CLIProxyAPI/v7/sdk/config" "github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginapi" + log "github.com/sirupsen/logrus" + logtest "github.com/sirupsen/logrus/hooks/test" "gopkg.in/yaml.v3" ) @@ -666,6 +668,48 @@ func TestHealthz(t *testing.T) { }) } +func TestHealthzSkipsAccessLogging(t *testing.T) { + server := newTestServer(t) + logger := log.StandardLogger() + previousHooks := logger.ReplaceHooks(make(log.LevelHooks)) + previousLevel := logger.GetLevel() + hook := logtest.NewLocal(logger) + logger.SetLevel(log.InfoLevel) + t.Cleanup(func() { + logger.ReplaceHooks(previousHooks) + logger.SetLevel(previousLevel) + }) + + for _, method := range []string{http.MethodGet, http.MethodHead} { + t.Run(method, func(t *testing.T) { + hook.Reset() + recorder := httptest.NewRecorder() + server.engine.ServeHTTP(recorder, httptest.NewRequest(method, "/healthz", nil)) + if recorder.Code != http.StatusOK { + t.Fatalf("health probe status = %d, want 200", recorder.Code) + } + for _, entry := range hook.AllEntries() { + if _, isAccessLog := entry.Data["request_id"]; isAccessLog && strings.Contains(entry.Message, `"/healthz"`) { + t.Errorf("health probe emitted an access log: %s", entry.Message) + } + } + + hook.Reset() + ordinary := httptest.NewRecorder() + server.engine.ServeHTTP(ordinary, httptest.NewRequest(http.MethodGet, "/healthz-access-log-control", nil)) + if ordinary.Code != http.StatusNotFound { + t.Fatalf("control status = %d, want 404", ordinary.Code) + } + for _, entry := range hook.AllEntries() { + if _, isAccessLog := entry.Data["request_id"]; isAccessLog && strings.Contains(entry.Message, `"/healthz-access-log-control"`) { + return + } + } + t.Error("ordinary request did not emit an access log after health probe") + }) + } +} + func TestCodexLiveRoutesRequireAuthAndAreRegistered(t *testing.T) { server := newTestServer(t)