logger_test.go (4609B)
1 package logger 2 3 import ( 4 "encoding/json" 5 "os" 6 "path/filepath" 7 "strings" 8 "testing" 9 ) 10 11 func TestJSONLogger(t *testing.T) { 12 // Create a temp file for the log 13 dir := t.TempDir() 14 logPath := filepath.Join(dir, "test.log") 15 16 lg, err := New(logPath, "json") 17 if err != nil { 18 t.Fatalf("New() returned error: %v", err) 19 } 20 defer lg.Close() 21 22 // Write an info entry with fields 23 lg.Info("synced", map[string]interface{}{ 24 "file": "main.go", 25 "size": 2150, 26 }) 27 28 // Read the file contents 29 data, err := os.ReadFile(logPath) 30 if err != nil { 31 t.Fatalf("failed to read log file: %v", err) 32 } 33 34 line := strings.TrimSpace(string(data)) 35 if line == "" { 36 t.Fatal("log file is empty") 37 } 38 39 // Parse as JSON 40 var entry map[string]interface{} 41 if err := json.Unmarshal([]byte(line), &entry); err != nil { 42 t.Fatalf("log entry is not valid JSON: %v\nline: %s", err, line) 43 } 44 45 // Verify required fields 46 if entry["level"] != "info" { 47 t.Errorf("expected level=info, got %v", entry["level"]) 48 } 49 if entry["event"] != "synced" { 50 t.Errorf("expected event=synced, got %v", entry["event"]) 51 } 52 if entry["file"] != "main.go" { 53 t.Errorf("expected file=main.go, got %v", entry["file"]) 54 } 55 // JSON numbers are float64 by default 56 if entry["size"] != float64(2150) { 57 t.Errorf("expected size=2150, got %v", entry["size"]) 58 } 59 if _, ok := entry["time"]; !ok { 60 t.Error("expected time field to be present") 61 } 62 } 63 64 func TestTextLogger(t *testing.T) { 65 // Create a temp file for the log 66 dir := t.TempDir() 67 logPath := filepath.Join(dir, "test.log") 68 69 lg, err := New(logPath, "text") 70 if err != nil { 71 t.Fatalf("New() returned error: %v", err) 72 } 73 defer lg.Close() 74 75 // Write an info entry with fields 76 lg.Info("synced", map[string]interface{}{ 77 "file": "main.go", 78 "size": 2150, 79 }) 80 81 // Read the file contents 82 data, err := os.ReadFile(logPath) 83 if err != nil { 84 t.Fatalf("failed to read log file: %v", err) 85 } 86 87 line := strings.TrimSpace(string(data)) 88 if line == "" { 89 t.Fatal("log file is empty") 90 } 91 92 // Verify text format contains INF and event name 93 if !strings.Contains(line, "INF") { 94 t.Errorf("expected line to contain 'INF', got: %s", line) 95 } 96 if !strings.Contains(line, "synced") { 97 t.Errorf("expected line to contain 'synced', got: %s", line) 98 } 99 if !strings.Contains(line, "file=main.go") { 100 t.Errorf("expected line to contain 'file=main.go', got: %s", line) 101 } 102 } 103 104 func TestDefaultFormatIsText(t *testing.T) { 105 dir := t.TempDir() 106 logPath := filepath.Join(dir, "test.log") 107 108 lg, err := New(logPath, "") 109 if err != nil { 110 t.Fatalf("New() returned error: %v", err) 111 } 112 defer lg.Close() 113 114 if lg.format != "text" { 115 t.Errorf("expected default format to be 'text', got %q", lg.format) 116 } 117 } 118 119 func TestWarnLevel(t *testing.T) { 120 dir := t.TempDir() 121 logPath := filepath.Join(dir, "test.log") 122 123 lg, err := New(logPath, "text") 124 if err != nil { 125 t.Fatalf("New() returned error: %v", err) 126 } 127 defer lg.Close() 128 129 lg.Warn("disk_low", map[string]interface{}{ 130 "pct": 95, 131 }) 132 133 data, err := os.ReadFile(logPath) 134 if err != nil { 135 t.Fatalf("failed to read log file: %v", err) 136 } 137 138 line := strings.TrimSpace(string(data)) 139 if !strings.Contains(line, "WRN") { 140 t.Errorf("expected line to contain 'WRN', got: %s", line) 141 } 142 if !strings.Contains(line, "disk_low") { 143 t.Errorf("expected line to contain 'disk_low', got: %s", line) 144 } 145 } 146 147 func TestErrorLevel(t *testing.T) { 148 dir := t.TempDir() 149 logPath := filepath.Join(dir, "test.log") 150 151 lg, err := New(logPath, "json") 152 if err != nil { 153 t.Fatalf("New() returned error: %v", err) 154 } 155 defer lg.Close() 156 157 lg.Error("connection_failed", map[string]interface{}{ 158 "host": "example.com", 159 }) 160 161 data, err := os.ReadFile(logPath) 162 if err != nil { 163 t.Fatalf("failed to read log file: %v", err) 164 } 165 166 var entry map[string]interface{} 167 if err := json.Unmarshal([]byte(strings.TrimSpace(string(data))), &entry); err != nil { 168 t.Fatalf("not valid JSON: %v", err) 169 } 170 171 if entry["level"] != "error" { 172 t.Errorf("expected level=error, got %v", entry["level"]) 173 } 174 } 175 176 func TestDebugLevel(t *testing.T) { 177 dir := t.TempDir() 178 logPath := filepath.Join(dir, "test.log") 179 180 lg, err := New(logPath, "text") 181 if err != nil { 182 t.Fatalf("New() returned error: %v", err) 183 } 184 defer lg.Close() 185 186 lg.Debug("trace_check", nil) 187 188 data, err := os.ReadFile(logPath) 189 if err != nil { 190 t.Fatalf("failed to read log file: %v", err) 191 } 192 193 line := strings.TrimSpace(string(data)) 194 if !strings.Contains(line, "DBG") { 195 t.Errorf("expected line to contain 'DBG', got: %s", line) 196 } 197 if !strings.Contains(line, "trace_check") { 198 t.Errorf("expected line to contain 'trace_check', got: %s", line) 199 } 200 }