package inspur import ( "bufio" "regexp" "strings" "time" "git.mchus.pro/mchus/logpile/internal/models" ) var ( // Syslog format: timestamp hostname process: message syslogRegex = regexp.MustCompile(`^<(\d+)>\s*(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[^\s]*)\s+(\S+)\s+(\S+):\s*(.*)$`) ) // ParseSyslog parses syslog format logs func ParseSyslog(content []byte, sourcePath string) []models.Event { var events []models.Event // Determine severity from file path severity := determineSeverityFromPath(sourcePath) scanner := bufio.NewScanner(strings.NewReader(string(content))) lineNum := 0 for scanner.Scan() { lineNum++ line := strings.TrimSpace(scanner.Text()) if line == "" { continue } matches := syslogRegex.FindStringSubmatch(line) if matches == nil { continue } timestamp, err := time.Parse(time.RFC3339, matches[2]) if err != nil { // Try alternative format timestamp, err = time.Parse("2006-01-02T15:04:05.000000-07:00", matches[2]) if err != nil { continue } } event := models.Event{ ID: generateEventID(sourcePath, lineNum), Timestamp: timestamp, Source: matches[4], SensorType: "syslog", SensorName: matches[3], Description: matches[5], Severity: severity, RawData: line, } events = append(events, event) } return events } func determineSeverityFromPath(path string) models.Severity { pathLower := strings.ToLower(path) switch { case strings.Contains(pathLower, "emerg") || strings.Contains(pathLower, "alert") || strings.Contains(pathLower, "crit"): return models.SeverityCritical case strings.Contains(pathLower, "warn") || strings.Contains(pathLower, "error"): return models.SeverityWarning default: return models.SeverityInfo } } func generateEventID(source string, lineNum int) string { parts := strings.Split(source, "/") filename := parts[len(parts)-1] return strings.TrimSuffix(filename, ".log") + "_" + itoa(lineNum) } func itoa(i int) string { if i == 0 { return "0" } var b [20]byte pos := len(b) for i > 0 { pos-- b[pos] = byte('0' + i%10) i /= 10 } return string(b[pos:]) }