package inspurlegacy import ( "regexp" "strings" "time" "git.mchus.pro/mchus/logpile/internal/models" ) var blackboxLineRe = regexp.MustCompile(`^\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})\]\s*:\s*(.*)$`) const blackboxTimeLayout = "2006-01-02 15:04:05" // blackboxCritical / blackboxWarning classify the free-text message. var ( blackboxCritical = []string{"fault", "error", "under voltage protection", "power good detect pin changed from 1 to 0", "critical"} blackboxWarning = []string{"warning", "predfail", "changed from 0 to 1"} ) // ParseBlackbox parses blackbox.log ("[YYYY-MM-DD HH:MM:SS] : message"), the // BMC's persistent power/thermal/RAID fault ring buffer. func ParseBlackbox(content []byte) []models.Event { var events []models.Event seq := 0 for _, line := range strings.Split(string(content), "\n") { line = strings.TrimSpace(line) m := blackboxLineRe.FindStringSubmatch(line) if m == nil { continue } ts, err := time.Parse(blackboxTimeLayout, m[1]) if err != nil || bogusYear(ts) { continue } msg := strings.TrimSpace(m[2]) msg = strings.TrimPrefix(msg, "[*]") seq++ events = append(events, models.Event{ ID: "blackbox_" + ts.Format("20060102T150405") + "_" + itoa(seq), Timestamp: ts, Source: "BMC/blackbox", SensorType: "blackbox", SensorName: blackboxSubject(msg), Severity: classify(msg, blackboxCritical, blackboxWarning), Description: msg, RawData: line, }) } return events } var blackboxSubjectRe = regexp.MustCompile(`^(PSU-?\d+|psu \d+|RAID|raid\s*\d+|CPU-?\d+|FAN-?\d+)`) func blackboxSubject(msg string) string { if m := blackboxSubjectRe.FindString(msg); m != "" { return strings.TrimSpace(m) } return "blackbox" } func classify(msg string, critical, warning []string) models.Severity { low := strings.ToLower(msg) for _, p := range critical { if strings.Contains(low, p) { return models.SeverityCritical } } for _, p := range warning { if strings.Contains(low, p) { return models.SeverityWarning } } return models.SeverityInfo } func itoa(i int) string { if i == 0 { return "0" } neg := i < 0 if neg { i = -i } var b [20]byte pos := len(b) for i > 0 { pos-- b[pos] = byte('0' + i%10) i /= 10 } if neg { pos-- b[pos] = '-' } return string(b[pos:]) }