Files
2026-05-22 09:17:39 +08:00

63 lines
1.5 KiB
Go

package logweb
import (
"regexp"
"strings"
)
var (
logLineRE = regexp.MustCompile(`^\[(app|pull|push)\]\s+(\d{4}/\d{2}/\d{2}\s+\d{2}:\d{2}:\d{2})\s+(.*)$`)
sepRE = regexp.MustCompile(`^=+\s*.+\s*=+$`)
)
// LogLine 解析后的日志行。
type LogLine struct {
LineNo int `json:"lineNo"`
Tag string `json:"tag,omitempty"`
Time string `json:"time,omitempty"`
Message string `json:"message"`
Level string `json:"level"`
IsSeparator bool `json:"isSeparator"`
Raw string `json:"raw"`
}
// ParseLogLines 解析原始行。
func ParseLogLines(raw []string) []LogLine {
out := make([]LogLine, 0, len(raw))
for i, line := range raw {
l := LogLine{LineNo: i + 1, Raw: line, Level: "info"}
if sepRE.MatchString(line) {
l.IsSeparator = true
l.Level = "sep"
l.Message = line
out = append(out, l)
continue
}
if m := logLineRE.FindStringSubmatch(line); len(m) == 4 {
l.Tag = m[1]
l.Time = m[2]
l.Message = m[3]
l.Level = classifyLevel(l.Message)
} else {
l.Message = line
l.Level = classifyLevel(line)
}
out = append(out, l)
}
return out
}
func classifyLevel(msg string) string {
low := strings.ToLower(msg)
switch {
case strings.Contains(low, "fail") || strings.Contains(low, "err") || strings.Contains(low, "error"):
return "error"
case strings.Contains(low, "warning") || strings.Contains(low, "warn"):
return "warn"
case strings.Contains(low, " ok ") || strings.HasPrefix(low, "ok ") || strings.Contains(low, "ok=true"):
return "ok"
default:
return "info"
}
}