fix(logging): 修复 warn 级别下系统日志空白问题

- 新增 logger.WriteSinkEvent,支持旁路写入 sink,不受全局级别门控影响\n- 在 http.access 中间件中,当 info 被门控时补写 sink,保障 Ops 系统日志可索引\n- 增加 level=warn 场景回归测试,验证访问日志仍可入库
This commit is contained in:
yangjianbo
2026-02-12 19:19:11 +08:00
parent 3511376c2c
commit b6aaee01ce
3 changed files with 127 additions and 1 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"
@@ -32,9 +33,17 @@ func (s *testLogSink) list() []*logger.LogEvent {
}
func initMiddlewareTestLogger(t *testing.T) *testLogSink {
return initMiddlewareTestLoggerWithLevel(t, "debug")
}
func initMiddlewareTestLoggerWithLevel(t *testing.T, level string) *testLogSink {
t.Helper()
level = strings.TrimSpace(level)
if level == "" {
level = "debug"
}
if err := logger.Init(logger.InitOptions{
Level: "debug",
Level: level,
Format: "json",
ServiceName: "sub2api",
Environment: "test",
@@ -191,3 +200,50 @@ func TestLogger_HealthPathSkipped(t *testing.T) {
t.Fatalf("health endpoint should not write access log")
}
}
func TestLogger_AccessLogStillIndexedWhenLevelWarn(t *testing.T) {
gin.SetMode(gin.TestMode)
sink := initMiddlewareTestLoggerWithLevel(t, "warn")
r := gin.New()
r.Use(RequestLogger())
r.Use(Logger())
r.GET("/api/test", func(c *gin.Context) {
c.Status(http.StatusCreated)
})
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/api/test", nil)
r.ServeHTTP(w, req)
if w.Code != http.StatusCreated {
t.Fatalf("status=%d", w.Code)
}
events := sink.list()
if len(events) == 0 {
t.Fatalf("expected access log event to be indexed when level=warn")
}
found := false
for _, event := range events {
if event == nil || event.Message != "http request completed" {
continue
}
found = true
if event.Level != "info" {
t.Fatalf("event level=%q, want info", event.Level)
}
if event.Component != "http.access" && event.Fields["component"] != "http.access" {
t.Fatalf("event component mismatch: component=%q fields=%v", event.Component, event.Fields["component"])
}
if _, ok := event.Fields["status_code"]; !ok {
t.Fatalf("status_code field missing: %+v", event.Fields)
}
if _, ok := event.Fields["request_id"]; !ok {
t.Fatalf("request_id field missing: %+v", event.Fields)
}
}
if !found {
t.Fatalf("access log event not found")
}
}