feat(log): 全面重构日志系统,支持日志级别、去除ANSI乱码并抑制高频轮询

This commit is contained in:
yml2213
2026-09-18 15:04:38 +08:00
parent 20bde97d7a
commit ec76844da8
15 changed files with 415 additions and 100 deletions
+64 -37
View File
@@ -1,47 +1,74 @@
package applog
import (
"os"
"path/filepath"
"bytes"
"log"
"strings"
"testing"
"time"
)
func TestDailyFileWriterRotatesAndCleans(t *testing.T) {
dir := t.TempDir()
logFile := filepath.Join(dir, "app.log")
w, err := newDailyFileWriter(logFile)
if err != nil {
t.Fatalf("new writer: %v", err)
}
defer w.Close()
// 写入当天日志,文件应按 app-YYYYMMDD.log 命名
today := time.Now().Format("20060102")
if _, err := w.Write([]byte("line1\n")); err != nil {
t.Fatalf("write: %v", err)
}
todayPath := filepath.Join(dir, "app-"+today+".log")
if _, err := os.Stat(todayPath); err != nil {
t.Fatalf("today log file missing: %v", err)
}
// 旧格式 app.log 不应被创建
if _, err := os.Stat(logFile); err == nil {
t.Fatalf("old-style app.log should not be created")
func TestParseLevel(t *testing.T) {
tests := []struct {
input string
expected Level
}{
{"debug", LevelDebug},
{"DEBUG", LevelDebug},
{"info", LevelInfo},
{"INFO", LevelInfo},
{"warn", LevelWarn},
{"warning", LevelWarn},
{"WARN", LevelWarn},
{"error", LevelError},
{"ERROR", LevelError},
{"unknown", LevelInfo},
{"", LevelInfo},
}
// 构造过期文件,cleanup 应删除(保留 30 天,这里用 3 天验证)
old := filepath.Join(dir, "app-20260701.log")
if err := os.WriteFile(old, []byte("old"), 0o644); err != nil {
t.Fatalf("create old file: %v", err)
}
w.cleanup(time.Now())
if _, err := os.Stat(old); err == nil {
t.Fatalf("old log file should be cleaned")
}
// 当天的文件应保留
if _, err := os.Stat(todayPath); err != nil {
t.Fatalf("today log file should be kept")
for _, tc := range tests {
got := ParseLevel(tc.input)
if got != tc.expected {
t.Errorf("ParseLevel(%q) = %v, want %v", tc.input, got, tc.expected)
}
}
}
func TestLogLevelFiltering(t *testing.T) {
var buf bytes.Buffer
log.SetOutput(&buf)
defer log.SetOutput(log.Writer())
SetLevel("warn")
buf.Reset()
Debugf("this is debug: %d", 1)
if buf.Len() > 0 {
t.Errorf("expected debug to be filtered out, got %q", buf.String())
}
buf.Reset()
Infof("this is info: %d", 2)
if buf.Len() > 0 {
t.Errorf("expected info to be filtered out, got %q", buf.String())
}
buf.Reset()
Warnf("this is warn: %d", 3)
if !strings.Contains(buf.String(), "[WARN] this is warn: 3") {
t.Errorf("expected warn to be logged, got %q", buf.String())
}
buf.Reset()
Errorf("this is error: %d", 4)
if !strings.Contains(buf.String(), "[ERROR] this is error: 4") {
t.Errorf("expected error to be logged, got %q", buf.String())
}
// Now switch to debug
SetLevel("debug")
buf.Reset()
Debugf("debug now visible")
if !strings.Contains(buf.String(), "[DEBUG] debug now visible") {
t.Errorf("expected debug to be logged after SetLevel(debug), got %q", buf.String())
}
}