From 4acd6a1ece8268bcc2d20484baf7891e45f726d3 Mon Sep 17 00:00:00 2001 From: "Yousif N.Abbass" Date: Wed, 28 Jun 2023 20:30:58 +0300 Subject: [PATCH 1/2] Levels Colorization --- .idea/.gitignore | 8 ++++ .idea/log.iml | 9 ++++ .idea/modules.xml | 8 ++++ .idea/vcs.xml | 6 +++ color.go | 106 ++++++++++++++++++++++++++++++++++++++++++++++ color_test.go | 89 ++++++++++++++++++++++++++++++++++++++ log.go | 3 ++ 7 files changed, 229 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/log.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 color.go create mode 100644 color_test.go diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/log.iml b/.idea/log.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/log.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0882239 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/color.go b/color.go new file mode 100644 index 0000000..52a68fd --- /dev/null +++ b/color.go @@ -0,0 +1,106 @@ +package log + +import "fmt" + +// ColorizeLevel assigns a specific color to each log level based on its string representation. +func ColorizeLevel(level Level) { + switch level.String() { + case "DEBUG": + PrintColor(DebugColor{}) + case "INFO": + PrintColor(InfoColor{}) + case "NOTICE": + PrintColor(NoticeColor{}) + case "WARN": + PrintColor(WarnColor{}) + case "ERROR": + PrintColor(ErrorColor{}) + case "PANIC": + PrintColor(PanicColor{}) + case "ALERT": + PrintColor(AlertColor{}) + case "FATAL": + PrintColor(FatalColor{}) + default: + PrintColor(DefaultColor{}) + } +} + +// Custom color types for each log level. +type DefaultColor struct{ value string } +type DebugColor struct{ value string } +type InfoColor struct{ value string } +type NoticeColor struct{ value string } +type WarnColor struct{ value string } +type ErrorColor struct{ value string } +type PanicColor struct{ value string } +type AlertColor struct{ value string } +type FatalColor struct{ value string } + +// Methods for each color type that returns the corresponding ANSI escape code. +// These methods implement the Color interface. + +// Set Debug Color +func (LevelColor DebugColor) getLevelColor() string { + LevelColor.value = "\033[36m" + return LevelColor.value +} + +// Set Info Color +func (LevelColor InfoColor) getLevelColor() string { + LevelColor.value = "\033[32m" + return LevelColor.value +} + +// Set Notice Color +func (LevelColor NoticeColor) getLevelColor() string { + LevelColor.value = "\033[33m" + return LevelColor.value +} + +// Set Warn Color +func (LevelColor WarnColor) getLevelColor() string { + LevelColor.value = "\033[35m" + return LevelColor.value +} + +// Set Error Color +func (LevelColor ErrorColor) getLevelColor() string { + LevelColor.value = "\033[31m" + return LevelColor.value +} + +// Set Panic Color +func (LevelColor PanicColor) getLevelColor() string { + LevelColor.value = "\033[91m" + return LevelColor.value +} + +// Set Alert Color +func (LevelColor AlertColor) getLevelColor() string { + LevelColor.value = "\033[93m" + return LevelColor.value +} + +// Set Fatal Color +func (LevelColor FatalColor) getLevelColor() string { + LevelColor.value = "\033[95m" + return LevelColor.value +} + +// Set Default Color +func (LevelColor DefaultColor) getLevelColor() string { + LevelColor.value = "\033[0m" + return LevelColor.value +} + +// Color interface defines the getLevelColor method to get the ANSI escape code. +type Color interface { + getLevelColor() string +} + +// PrintColor sets the appropriate color for the log level and prints it. +func PrintColor(C Color) { + LevelColor := C.getLevelColor() + fmt.Print(LevelColor) +} diff --git a/color_test.go b/color_test.go new file mode 100644 index 0000000..1e7922b --- /dev/null +++ b/color_test.go @@ -0,0 +1,89 @@ +package log + +import ( + "bytes" + "fmt" + "os" + "testing" +) + +// CustomWriter is a custom writer that wraps bytes.Buffer and implements io.Writer +type CustomWriter struct { + buffer *bytes.Buffer +} + +// Write writes the data to the underlying buffer +func (w *CustomWriter) Write(p []byte) (n int, err error) { + return w.buffer.Write(p) +} + +// File returns the underlying *os.File +func (w *CustomWriter) File() *os.File { + return os.Stdout +} + +func TestColorizeLevel(t *testing.T) { + buff := new(bytes.Buffer) + + // Create a custom writer that wraps the buffer + customWriter := &CustomWriter{buffer: buff} + + // Redirect stdout to the buffer + old := os.Stdout + os.Stdout = customWriter.File() + + // Test cases + testCases := []struct { + level Level + color string + expected string + expectedErr error + }{ + {DebugLevel, "\033[36m", "", nil}, // Expected ANSI escape code for DEBUG: Cyan + {InfoLevel, "\033[32m", "", nil}, // Expected ANSI escape code for INFO: Green + {NoticeLevel, "\033[33m", "", nil}, // Expected ANSI escape code for NOTICE: Yellow + {WarnLevel, "\033[35m", "", nil}, // Expected ANSI escape code for WARN: Magenta + {ErrorLevel, "\033[31m", "", nil}, // Expected ANSI escape code for ERROR: Red + {PanicLevel, "\033[91m", "", nil}, // Expected ANSI escape code for PANIC: Light Red + {AlertLevel, "\033[93m", "", nil}, // Expected ANSI escape code for ALERT: Light Yellow + {FatalLevel, "\033[95m", "", nil}, // Expected ANSI escape code for FATAL: Light Magenta + {InfoLevel, "\033[32m", "", nil}, // Invalid color (for testing error handling) + //{UNKNOWN, "\033[0m", "\033[0m", nil}, // Expected ANSI escape code for unknown level: Reset to default + } + + // Iterate over test cases + for _, tc := range testCases { + t.Run(tc.level.String(), func(t *testing.T) { + // Reset the buffer + buff.Reset() + + // Call the ColorizeLevel function + err := func() (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic: %v", r) + } + }() + ColorizeLevel(tc.level) + return nil + }() + + // Check if an error occurred (for error handling testing) + if tc.expectedErr != nil { + if err == nil || err.Error() != tc.expectedErr.Error() { + t.Errorf("Expected error: %v, but got: %v", tc.expectedErr, err) + } + return + } + + // Check if the printed output matches the expected ANSI escape code + actual := buff.String() + if actual != tc.expected { + t.Errorf("Expected: %s, but got: %s", tc.expected, actual) + } + }) + } + + // Restore stdout + os.Stdout = old +} diff --git a/log.go b/log.go index 53275df..5b353fd 100644 --- a/log.go +++ b/log.go @@ -150,6 +150,9 @@ func HandleEntry(e Entry) { } e.Timestamp = time.Now() + //Adding colors for each output level + ColorizeLevel(e.Level) + rw.RLock() for _, h := range logHandlers[e.Level] { h.Log(e) From 3678423771b7594712b0863802b46aad76d2a47c Mon Sep 17 00:00:00 2001 From: "Yousif N.Abbass" Date: Wed, 28 Jun 2023 20:31:56 +0300 Subject: [PATCH 2/2] Levels Colorization --- .idea/.gitignore | 8 -------- .idea/log.iml | 9 --------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 4 files changed, 31 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/log.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/log.iml b/.idea/log.iml deleted file mode 100644 index 5e764c4..0000000 --- a/.idea/log.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 0882239..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file