feat: add rule-based log syntax highlighter and tests

This commit is contained in:
hunchulchoi 2026-06-04 17:42:29 +09:00
parent 7e7aadc207
commit 137486d721
2 changed files with 82 additions and 0 deletions

41
pkg/utils/logs.go Normal file
View file

@ -0,0 +1,41 @@
package utils
import (
"regexp"
"strings"
)
var (
errRegex = regexp.MustCompile(`(?i)\b(error|err|critical|fatal)\b`)
warnRegex = regexp.MustCompile(`(?i)\b(warning|warn)\b`)
infoRegex = regexp.MustCompile(`(?i)\b(info)\b`)
debugRegex = regexp.MustCompile(`(?i)\b(debug)\b`)
timestampRegex = regexp.MustCompile(`\b\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?\b`)
)
// ColoriseLog applies basic ANSI syntax highlighting to typical log statements.
func ColoriseLog(line string) string {
if strings.Contains(line, "\x1b[") {
return line
}
line = timestampRegex.ReplaceAllStringFunc(line, func(ts string) string {
return "\x1b[90m" + ts + "\x1b[0m"
})
line = errRegex.ReplaceAllStringFunc(line, func(match string) string {
return "\x1b[31;1m" + match + "\x1b[0m"
})
line = warnRegex.ReplaceAllStringFunc(line, func(match string) string {
return "\x1b[33;1m" + match + "\x1b[0m"
})
line = infoRegex.ReplaceAllStringFunc(line, func(match string) string {
return "\x1b[32m" + match + "\x1b[0m"
})
line = debugRegex.ReplaceAllStringFunc(line, func(match string) string {
return "\x1b[34m" + match + "\x1b[0m"
})
return line
}

41
pkg/utils/logs_test.go Normal file
View file

@ -0,0 +1,41 @@
package utils
import (
"strings"
"testing"
)
func TestColoriseLog(t *testing.T) {
tests := []struct {
name string
input string
contains []string
}{
{
name: "Highlight error log level",
input: "ERROR: database failed to connect",
contains: []string{"\x1b[31;1mERROR\x1b[0m"},
},
{
name: "Highlight warning log level",
input: "[WARN] deprecation warning",
contains: []string{"\x1b[33;1mWARN\x1b[0m"},
},
{
name: "Highlight timestamp",
input: "2026-06-04T12:00:00Z something happened",
contains: []string{"\x1b[90m2026-06-04T12:00:00Z\x1b[0m"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := ColoriseLog(tt.input)
for _, c := range tt.contains {
if !strings.Contains(got, c) {
t.Errorf("expected %q to contain %q, but it was %q", got, c, got)
}
}
})
}
}