Skip to content

Commit 4acd6a1

Browse files
committed
Levels Colorization
1 parent d2677a2 commit 4acd6a1

File tree

7 files changed

+229
-0
lines changed

7 files changed

+229
-0
lines changed

.idea/.gitignore

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/log.iml

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

color.go

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package log
2+
3+
import "fmt"
4+
5+
// ColorizeLevel assigns a specific color to each log level based on its string representation.
6+
func ColorizeLevel(level Level) {
7+
switch level.String() {
8+
case "DEBUG":
9+
PrintColor(DebugColor{})
10+
case "INFO":
11+
PrintColor(InfoColor{})
12+
case "NOTICE":
13+
PrintColor(NoticeColor{})
14+
case "WARN":
15+
PrintColor(WarnColor{})
16+
case "ERROR":
17+
PrintColor(ErrorColor{})
18+
case "PANIC":
19+
PrintColor(PanicColor{})
20+
case "ALERT":
21+
PrintColor(AlertColor{})
22+
case "FATAL":
23+
PrintColor(FatalColor{})
24+
default:
25+
PrintColor(DefaultColor{})
26+
}
27+
}
28+
29+
// Custom color types for each log level.
30+
type DefaultColor struct{ value string }
31+
type DebugColor struct{ value string }
32+
type InfoColor struct{ value string }
33+
type NoticeColor struct{ value string }
34+
type WarnColor struct{ value string }
35+
type ErrorColor struct{ value string }
36+
type PanicColor struct{ value string }
37+
type AlertColor struct{ value string }
38+
type FatalColor struct{ value string }
39+
40+
// Methods for each color type that returns the corresponding ANSI escape code.
41+
// These methods implement the Color interface.
42+
43+
// Set Debug Color
44+
func (LevelColor DebugColor) getLevelColor() string {
45+
LevelColor.value = "\033[36m"
46+
return LevelColor.value
47+
}
48+
49+
// Set Info Color
50+
func (LevelColor InfoColor) getLevelColor() string {
51+
LevelColor.value = "\033[32m"
52+
return LevelColor.value
53+
}
54+
55+
// Set Notice Color
56+
func (LevelColor NoticeColor) getLevelColor() string {
57+
LevelColor.value = "\033[33m"
58+
return LevelColor.value
59+
}
60+
61+
// Set Warn Color
62+
func (LevelColor WarnColor) getLevelColor() string {
63+
LevelColor.value = "\033[35m"
64+
return LevelColor.value
65+
}
66+
67+
// Set Error Color
68+
func (LevelColor ErrorColor) getLevelColor() string {
69+
LevelColor.value = "\033[31m"
70+
return LevelColor.value
71+
}
72+
73+
// Set Panic Color
74+
func (LevelColor PanicColor) getLevelColor() string {
75+
LevelColor.value = "\033[91m"
76+
return LevelColor.value
77+
}
78+
79+
// Set Alert Color
80+
func (LevelColor AlertColor) getLevelColor() string {
81+
LevelColor.value = "\033[93m"
82+
return LevelColor.value
83+
}
84+
85+
// Set Fatal Color
86+
func (LevelColor FatalColor) getLevelColor() string {
87+
LevelColor.value = "\033[95m"
88+
return LevelColor.value
89+
}
90+
91+
// Set Default Color
92+
func (LevelColor DefaultColor) getLevelColor() string {
93+
LevelColor.value = "\033[0m"
94+
return LevelColor.value
95+
}
96+
97+
// Color interface defines the getLevelColor method to get the ANSI escape code.
98+
type Color interface {
99+
getLevelColor() string
100+
}
101+
102+
// PrintColor sets the appropriate color for the log level and prints it.
103+
func PrintColor(C Color) {
104+
LevelColor := C.getLevelColor()
105+
fmt.Print(LevelColor)
106+
}

color_test.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package log
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"os"
7+
"testing"
8+
)
9+
10+
// CustomWriter is a custom writer that wraps bytes.Buffer and implements io.Writer
11+
type CustomWriter struct {
12+
buffer *bytes.Buffer
13+
}
14+
15+
// Write writes the data to the underlying buffer
16+
func (w *CustomWriter) Write(p []byte) (n int, err error) {
17+
return w.buffer.Write(p)
18+
}
19+
20+
// File returns the underlying *os.File
21+
func (w *CustomWriter) File() *os.File {
22+
return os.Stdout
23+
}
24+
25+
func TestColorizeLevel(t *testing.T) {
26+
buff := new(bytes.Buffer)
27+
28+
// Create a custom writer that wraps the buffer
29+
customWriter := &CustomWriter{buffer: buff}
30+
31+
// Redirect stdout to the buffer
32+
old := os.Stdout
33+
os.Stdout = customWriter.File()
34+
35+
// Test cases
36+
testCases := []struct {
37+
level Level
38+
color string
39+
expected string
40+
expectedErr error
41+
}{
42+
{DebugLevel, "\033[36m", "", nil}, // Expected ANSI escape code for DEBUG: Cyan
43+
{InfoLevel, "\033[32m", "", nil}, // Expected ANSI escape code for INFO: Green
44+
{NoticeLevel, "\033[33m", "", nil}, // Expected ANSI escape code for NOTICE: Yellow
45+
{WarnLevel, "\033[35m", "", nil}, // Expected ANSI escape code for WARN: Magenta
46+
{ErrorLevel, "\033[31m", "", nil}, // Expected ANSI escape code for ERROR: Red
47+
{PanicLevel, "\033[91m", "", nil}, // Expected ANSI escape code for PANIC: Light Red
48+
{AlertLevel, "\033[93m", "", nil}, // Expected ANSI escape code for ALERT: Light Yellow
49+
{FatalLevel, "\033[95m", "", nil}, // Expected ANSI escape code for FATAL: Light Magenta
50+
{InfoLevel, "\033[32m", "", nil}, // Invalid color (for testing error handling)
51+
//{UNKNOWN, "\033[0m", "\033[0m", nil}, // Expected ANSI escape code for unknown level: Reset to default
52+
}
53+
54+
// Iterate over test cases
55+
for _, tc := range testCases {
56+
t.Run(tc.level.String(), func(t *testing.T) {
57+
// Reset the buffer
58+
buff.Reset()
59+
60+
// Call the ColorizeLevel function
61+
err := func() (err error) {
62+
defer func() {
63+
if r := recover(); r != nil {
64+
err = fmt.Errorf("panic: %v", r)
65+
}
66+
}()
67+
ColorizeLevel(tc.level)
68+
return nil
69+
}()
70+
71+
// Check if an error occurred (for error handling testing)
72+
if tc.expectedErr != nil {
73+
if err == nil || err.Error() != tc.expectedErr.Error() {
74+
t.Errorf("Expected error: %v, but got: %v", tc.expectedErr, err)
75+
}
76+
return
77+
}
78+
79+
// Check if the printed output matches the expected ANSI escape code
80+
actual := buff.String()
81+
if actual != tc.expected {
82+
t.Errorf("Expected: %s, but got: %s", tc.expected, actual)
83+
}
84+
})
85+
}
86+
87+
// Restore stdout
88+
os.Stdout = old
89+
}

log.go

+3
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ func HandleEntry(e Entry) {
150150
}
151151
e.Timestamp = time.Now()
152152

153+
//Adding colors for each output level
154+
ColorizeLevel(e.Level)
155+
153156
rw.RLock()
154157
for _, h := range logHandlers[e.Level] {
155158
h.Log(e)

0 commit comments

Comments
 (0)