Files
upkg/logger/logger_test.go
2026-01-17 17:27:33 +08:00

327 lines
6.2 KiB
Go

package logger
import (
"bytes"
"context"
"strings"
"testing"
)
func TestTextFormat(t *testing.T) {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithFormat(TEXT),
WithTimeFormat("2006-01-02"),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
l.Info("hello %s", "world")
output := buf.String()
if !strings.Contains(output, "hello world") {
t.Errorf("expected 'hello world' in output, got: %s", output)
}
}
func TestJSONFormat(t *testing.T) {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithFormat(JSON),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
l.Info("test message")
output := buf.String()
if !strings.Contains(output, `"message":"test message"`) {
t.Errorf("expected JSON message in output, got: %s", output)
}
if !strings.Contains(output, `"level":"INFO"`) {
t.Errorf("expected level INFO in output, got: %s", output)
}
}
func TestWithFields(t *testing.T) {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithFormat(TEXT),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
l.InfoField("user logged in",
"user_id", 123,
"action", "login",
)
output := buf.String()
if !strings.Contains(output, "user_id=123") {
t.Errorf("expected user_id=123 in output, got: %s", output)
}
if !strings.Contains(output, "action=login") {
t.Errorf("expected action=login in output, got: %s", output)
}
}
func TestContextTraceID(t *testing.T) {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithFormat(JSON),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
ctx := context.WithValue(context.Background(), "trace_id", "req-123")
l.InfoCtx(ctx, "request processed")
output := buf.String()
if !strings.Contains(output, `"trace_id":"req-123"`) {
t.Errorf("expected trace_id in output, got: %s", output)
}
}
func TestCustomFieldKey(t *testing.T) {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithFormat(JSON),
WithFieldKey("request_id"),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
ctx := context.WithValue(context.Background(), "request_id", "req-456")
l.InfoCtx(ctx, "request processed")
output := buf.String()
if !strings.Contains(output, `"request_id":"req-456"`) {
t.Errorf("expected request_id in output, got: %s", output)
}
}
func TestCaller(t *testing.T) {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithFormat(TEXT),
WithCaller(true),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
l.Info("test caller")
output := buf.String()
if !strings.Contains(output, "logger_test.go:") {
t.Errorf("expected caller info in output, got: %s", output)
}
}
func TestLevelFiltering(t *testing.T) {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithLevel(ERROR),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
l.Debug("debug message")
l.Info("info message")
l.Error("error message")
output := buf.String()
if strings.Contains(output, "debug message") {
t.Errorf("debug message should be filtered out, got: %s", output)
}
if strings.Contains(output, "info message") {
t.Errorf("info message should be filtered out, got: %s", output)
}
if !strings.Contains(output, "error message") {
t.Errorf("error message should be present, got: %s", output)
}
}
func TestGlobalLogger(t *testing.T) {
buf := &bytes.Buffer{}
original := defaultLogger
defer func() { defaultLogger = original }()
defaultLogger = New(
WithOutputFile(""),
WithFormat(TEXT),
)
defaultLogger.mu.Lock()
defaultLogger.writer = buf
defaultLogger.mu.Unlock()
Info("global logger test")
output := buf.String()
if !strings.Contains(output, "global logger test") {
t.Errorf("expected global logger output, got: %s", output)
}
}
// Benchmarks
func benchmarkLogger(format Format, caller bool) *Logger {
buf := &bytes.Buffer{}
l := New(
WithOutputFile(""),
WithFormat(format),
WithCaller(caller),
)
l.mu.Lock()
l.writer = buf
l.mu.Unlock()
return l
}
func BenchmarkInfoText(b *testing.B) {
l := benchmarkLogger(TEXT, false)
msg := "hello world"
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.Info("hello world")
_ = msg
}
}
func BenchmarkInfoTextWithArgs(b *testing.B) {
l := benchmarkLogger(TEXT, false)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.Info("user %s logged in from %s", "john", "192.168.1.1")
}
}
func BenchmarkInfoJSON(b *testing.B) {
l := benchmarkLogger(JSON, false)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.Info("hello world")
}
}
func BenchmarkInfoField(b *testing.B) {
l := benchmarkLogger(TEXT, false)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.InfoField("user logged in",
"user_id", 123,
"action", "login",
"ip", "192.168.1.1",
)
}
}
func BenchmarkInfoFieldJSON(b *testing.B) {
l := benchmarkLogger(JSON, false)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.InfoField("user logged in",
"user_id", 123,
"action", "login",
"ip", "192.168.1.1",
)
}
}
func BenchmarkInfoWithCaller(b *testing.B) {
l := benchmarkLogger(TEXT, true)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.Info("hello world")
}
}
func BenchmarkInfoCtx(b *testing.B) {
l := benchmarkLogger(JSON, false)
ctx := context.WithValue(context.Background(), "trace_id", "req-123456789")
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.InfoCtx(ctx, "request processed")
}
}
func BenchmarkInfoFiltered(b *testing.B) {
l := New(
WithOutputFile(""),
WithLevel(ERROR),
)
l.mu.Lock()
l.writer = &bytes.Buffer{}
l.mu.Unlock()
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.Info("this should be filtered")
}
}
func BenchmarkManyFields(b *testing.B) {
l := benchmarkLogger(JSON, false)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
l.InfoField("event",
"field1", "value1",
"field2", "value2",
"field3", "value3",
"field4", "value4",
"field5", "value5",
"field6", "value6",
"field7", "value7",
"field8", "value8",
)
}
}
func BenchmarkGlobalInfo(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
Info("hello world")
}
}
func BenchmarkGlobalInfoField(b *testing.B) {
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
InfoField("event",
"key1", "value1",
"key2", "value2",
)
}
}