Files
logs/internal/ingest/syslog_parse.go
2026-03-30 15:26:16 +08:00

110 lines
2.2 KiB
Go

package ingest
import (
"fmt"
"regexp"
"strconv"
"strings"
)
var rePri = regexp.MustCompile(`^<(\d{1,3})>`)
type ParsedSyslog struct {
Priority int
Hostname string
Tag string
Message string
RawLine string
}
func parseSyslogPayload(payload []byte) ParsedSyslog {
line := strings.TrimSpace(string(payload))
p := ParsedSyslog{RawLine: line, Message: line}
if line == "" {
return p
}
rest := line
if m := rePri.FindStringSubmatch(line); len(m) == 2 {
if pri, err := strconv.Atoi(m[1]); err == nil {
p.Priority = pri
}
rest = line[len(m[0]):]
}
rest = strings.TrimSpace(rest)
fields := strings.SplitN(rest, " ", 6)
if len(fields) >= 2 && len(fields[0]) == 1 && fields[0][0] >= '1' && fields[0][0] <= '9' {
if len(fields) >= 4 {
p.Hostname = fields[2]
if len(fields) >= 6 {
p.Message = fields[5]
} else if len(fields) == 5 {
p.Message = fields[4]
}
}
return p
}
tokens := strings.SplitN(rest, " ", 3)
if len(tokens) >= 2 {
if len(tokens) >= 3 && isMonthAbbr(tokens[0]) {
p.Hostname = tokens[2]
if idx := strings.Index(rest, ": "); idx > 0 {
p.Message = strings.TrimSpace(rest[idx+2:])
}
} else {
p.Hostname = tokens[1]
if len(tokens) >= 3 {
tagMsg := tokens[2]
if idx := strings.Index(tagMsg, ": "); idx > 0 {
p.Tag = tagMsg[:idx]
p.Message = strings.TrimSpace(tagMsg[idx+2:])
} else {
p.Message = tagMsg
}
}
}
}
return p
}
func isMonthAbbr(s string) bool {
if len(s) < 3 {
return false
}
mons := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
for _, m := range mons {
if strings.HasPrefix(s, m) {
return true
}
}
return false
}
func syslogPriorityToSeverity(pri int) string {
sev := pri % 8
switch sev {
case 0, 1, 2:
return "critical"
case 3:
return "major"
case 4:
return "warning"
default:
return "info"
}
}
func formatSyslogSummary(p ParsedSyslog) string {
host := p.Hostname
if host == "" {
host = "unknown-host"
}
return fmt.Sprintf("%s: %s", host, truncate(p.Message, 512))
}
func truncate(s string, n int) string {
if len(s) <= n {
return s
}
return s[:n] + "..."
}