327 lines
6.2 KiB
Go
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",
|
|
)
|
|
}
|
|
}
|