package logger import ( "io" "log" "os" "strings" "testing" ) func TestInferStdLogLevel(t *testing.T) { cases := []struct { msg string want Level }{ {msg: "Warning: queue full", want: LevelWarn}, {msg: "Forward request failed: timeout", want: LevelError}, {msg: "[ERROR] upstream unavailable", want: LevelError}, {msg: "service started", want: LevelInfo}, {msg: "debug: cache miss", want: LevelDebug}, } for _, tc := range cases { got := inferStdLogLevel(tc.msg) if got != tc.want { t.Fatalf("inferStdLogLevel(%q)=%v want=%v", tc.msg, got, tc.want) } } } func TestNormalizeStdLogMessage(t *testing.T) { raw := " [TokenRefresh] cycle complete \n total=1 failed=0 \n" got := normalizeStdLogMessage(raw) want := "[TokenRefresh] cycle complete total=1 failed=0" if got != want { t.Fatalf("normalizeStdLogMessage()=%q want=%q", got, want) } } func TestStdLogBridgeRoutesLevels(t *testing.T) { origStdout := os.Stdout origStderr := os.Stderr stdoutR, stdoutW, err := os.Pipe() if err != nil { t.Fatalf("create stdout pipe: %v", err) } stderrR, stderrW, err := os.Pipe() if err != nil { t.Fatalf("create stderr pipe: %v", err) } os.Stdout = stdoutW os.Stderr = stderrW t.Cleanup(func() { os.Stdout = origStdout os.Stderr = origStderr _ = stdoutR.Close() _ = stdoutW.Close() _ = stderrR.Close() _ = stderrW.Close() }) if err := Init(InitOptions{ Level: "debug", Format: "json", ServiceName: "sub2api", Environment: "test", Output: OutputOptions{ ToStdout: true, ToFile: false, }, Sampling: SamplingOptions{Enabled: false}, }); err != nil { t.Fatalf("Init() error: %v", err) } log.Printf("service started") log.Printf("Warning: queue full") log.Printf("Forward request failed: timeout") Sync() _ = stdoutW.Close() _ = stderrW.Close() stdoutBytes, _ := io.ReadAll(stdoutR) stderrBytes, _ := io.ReadAll(stderrR) stdoutText := string(stdoutBytes) stderrText := string(stderrBytes) if !strings.Contains(stdoutText, "service started") { t.Fatalf("stdout missing info log: %s", stdoutText) } if !strings.Contains(stderrText, "Warning: queue full") { t.Fatalf("stderr missing warn log: %s", stderrText) } if !strings.Contains(stderrText, "Forward request failed: timeout") { t.Fatalf("stderr missing error log: %s", stderrText) } if !strings.Contains(stderrText, "\"legacy_stdlog\":true") { t.Fatalf("stderr missing legacy_stdlog marker: %s", stderrText) } } func TestLegacyPrintfRoutesLevels(t *testing.T) { origStdout := os.Stdout origStderr := os.Stderr stdoutR, stdoutW, err := os.Pipe() if err != nil { t.Fatalf("create stdout pipe: %v", err) } stderrR, stderrW, err := os.Pipe() if err != nil { t.Fatalf("create stderr pipe: %v", err) } os.Stdout = stdoutW os.Stderr = stderrW t.Cleanup(func() { os.Stdout = origStdout os.Stderr = origStderr _ = stdoutR.Close() _ = stdoutW.Close() _ = stderrR.Close() _ = stderrW.Close() }) if err := Init(InitOptions{ Level: "debug", Format: "json", ServiceName: "sub2api", Environment: "test", Output: OutputOptions{ ToStdout: true, ToFile: false, }, Sampling: SamplingOptions{Enabled: false}, }); err != nil { t.Fatalf("Init() error: %v", err) } LegacyPrintf("service.test", "request started") LegacyPrintf("service.test", "Warning: queue full") LegacyPrintf("service.test", "forward failed: timeout") Sync() _ = stdoutW.Close() _ = stderrW.Close() stdoutBytes, _ := io.ReadAll(stdoutR) stderrBytes, _ := io.ReadAll(stderrR) stdoutText := string(stdoutBytes) stderrText := string(stderrBytes) if !strings.Contains(stdoutText, "request started") { t.Fatalf("stdout missing info log: %s", stdoutText) } if !strings.Contains(stderrText, "Warning: queue full") { t.Fatalf("stderr missing warn log: %s", stderrText) } if !strings.Contains(stderrText, "forward failed: timeout") { t.Fatalf("stderr missing error log: %s", stderrText) } if !strings.Contains(stderrText, "\"legacy_printf\":true") { t.Fatalf("stderr missing legacy_printf marker: %s", stderrText) } if !strings.Contains(stderrText, "\"component\":\"service.test\"") { t.Fatalf("stderr missing component field: %s", stderrText) } }