package helpers import ( "fmt" "log/slog" "regexp" "strings" "time" "watch-tool/models" ) var ( syslogPattern = regexp.MustCompile(`^(\w{3} \d{2} \d{2}:\d{2}:\d{2}) ([^\s]+) ([^:]+):\s*(.*)$`) ) func ExtractSyslogHeader(line string) (models.SyslogFields, string) { var syslogFields models.SyslogFields matches := syslogPattern.FindStringSubmatch(strings.TrimSpace(line)) if len(matches) != 5 { return syslogFields, line } sysTime, err := ParseSyslogTimeToRFC3339(matches[1]) if err != nil { slog.Error("cant parse sys log time", "error", err) } syslogFields.SysLogTimestamp = sysTime syslogFields.Hostname = matches[2] syslogFields.ProcessInfo = matches[3] return syslogFields, matches[4] } func GetNamedGroup(match []string, regex *regexp.Regexp, groupName string) string { names := regex.SubexpNames() for i, name := range names { if name == groupName && i < len(match) { return match[i] } } return "" } func ParseRFC3339WithOptionalZ(timeStr string) (time.Time, error) { if !strings.HasSuffix(timeStr, "Z") && !strings.ContainsAny(timeStr[len(timeStr)-6:], "+-") { timeStr += "Z" } return time.Parse(time.RFC3339Nano, timeStr) } var deToEnMonth = map[string]string{ "Jan": "Jan", "Feb": "Feb", "Mär": "Mar", "Apr": "Apr", "Mai": "May", "Jun": "Jun", "Jul": "Jul", "Aug": "Aug", "Sep": "Sep", "Okt": "Oct", "Nov": "Nov", "Dez": "Dec", } func translateMonth(syslogTime string) string { for de, en := range deToEnMonth { if strings.HasPrefix(syslogTime, de) { return strings.Replace(syslogTime, de, en, 1) } } return syslogTime } func ParseSyslogTimeToRFC3339(syslogTime string) (time.Time, error) { const syslogLayout = "Jan 02 15:04:05" syslogTime = translateMonth(syslogTime) t, err := time.Parse(syslogLayout, syslogTime) if err != nil { return t, fmt.Errorf("cannot parse syslog time %q: %w", syslogTime, err) } now := time.Now() t = t.AddDate(now.Year(), 0, 0) return t, nil }