新增单行文本编码器与结构化 GORM 日志,统一错误记录与请求日志策略,收紧日志文件权限并修复按天切分与压缩,支付回调参数脱敏,生产强制阿里云短信,RequestID 校验防注入,日志文案中文化。
90 lines
2.7 KiB
Go
90 lines
2.7 KiB
Go
package logging
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestCompressDayAndPurge(t *testing.T) {
|
|
dir := t.TempDir()
|
|
loc := time.FixedZone("Asia/Shanghai", 8*60*60)
|
|
w := newDailyWriter(dir, "app", loc, 2)
|
|
|
|
// 准备三天明文日志
|
|
days := []string{"2026-07-01", "2026-07-10", "2026-07-11"}
|
|
for _, day := range days {
|
|
path := filepath.Join(dir, "app-"+day+".log")
|
|
if err := os.WriteFile(path, []byte(`{"msg":"hello `+day+`"}`+"\n"), 0o644); err != nil {
|
|
t.Fatalf("write log: %v", err)
|
|
}
|
|
}
|
|
|
|
// 压缩 7-10
|
|
if err := w.compressDay("2026-07-10"); err != nil {
|
|
t.Fatalf("compressDay: %v", err)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, "app-2026-07-10.log")); !os.IsNotExist(err) {
|
|
t.Fatalf("plain log should be removed after gzip, err=%v", err)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, "app-2026-07-10.log.gz")); err != nil {
|
|
t.Fatalf("gzip missing: %v", err)
|
|
}
|
|
|
|
// 以 7-12 为「现在」,保留 2 天(7-11、7-12),删除 7-11 之前。
|
|
now := time.Date(2026, 7, 12, 12, 0, 0, 0, loc)
|
|
if err := w.purgeOlderThan(now); err != nil {
|
|
t.Fatalf("purgeOlderThan: %v", err)
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, "app-2026-07-01.log")); !os.IsNotExist(err) {
|
|
t.Fatal("expired log should be purged")
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, "app-2026-07-10.log.gz")); !os.IsNotExist(err) {
|
|
t.Fatalf("expired gzip should be purged, err=%v", err)
|
|
}
|
|
// 7-11 仍应存在(cutoff 当天起保留)
|
|
if _, err := os.Stat(filepath.Join(dir, "app-2026-07-11.log")); err != nil {
|
|
t.Fatalf("recent plain should remain: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCompressDayReplacesCorruptedGzip(t *testing.T) {
|
|
dir := t.TempDir()
|
|
w := newDailyWriter(dir, "app", time.UTC, 0)
|
|
sourcePath := filepath.Join(dir, "app-2026-07-11.log")
|
|
gzipPath := sourcePath + ".gz"
|
|
if err := os.WriteFile(sourcePath, []byte("important log\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(gzipPath, []byte("broken"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := w.compressDay("2026-07-11"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := validateGzip(gzipPath); err != nil {
|
|
t.Fatalf("gzip should be valid: %v", err)
|
|
}
|
|
if _, err := os.Stat(sourcePath); !os.IsNotExist(err) {
|
|
t.Fatalf("source should be removed after successful compression, err=%v", err)
|
|
}
|
|
}
|
|
|
|
func TestCompressDayIdempotent(t *testing.T) {
|
|
dir := t.TempDir()
|
|
loc := time.UTC
|
|
w := newDailyWriter(dir, "app", loc, 0)
|
|
path := filepath.Join(dir, "app-2026-07-11.log")
|
|
if err := os.WriteFile(path, []byte("line\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := w.compressDay("2026-07-11"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := w.compressDay("2026-07-11"); err != nil {
|
|
t.Fatalf("second compress should be no-op: %v", err)
|
|
}
|
|
}
|