feat(inspur): source-PRI timezone timeline, PPIN serial, NVMe fault storage status
Event ingestion now uses the source syslog PRI and an explicit-offset timezone timeline instead of assuming host-local time. CPU PPIN is exported as the source-backed CPU serial, and an active NVMe fault SEL event promotes the matching drive's storage status. See ADL-056, ADL-057. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
07c270cda2
commit
e7b8a8badc
+19
-6
@@ -16,7 +16,7 @@ import (
|
||||
|
||||
// parserVersion - version of this parser module
|
||||
// IMPORTANT: Increment this version when making changes to parser logic!
|
||||
const parserVersion = "2.3"
|
||||
const parserVersion = "2.5"
|
||||
|
||||
func init() {
|
||||
parser.Register(&Parser{})
|
||||
@@ -96,6 +96,7 @@ func containsInspurMarkers(content []byte) bool {
|
||||
// Parse parses Inspur/Kaytus archive
|
||||
func (p *Parser) Parse(files []parser.ExtractedFile) (*models.AnalysisResult, error) {
|
||||
selLocation := inferInspurArchiveLocation(files)
|
||||
selTimezone := inferInspurTimezoneResolver(files, selLocation)
|
||||
|
||||
result := &models.AnalysisResult{
|
||||
Events: make([]models.Event, 0),
|
||||
@@ -239,15 +240,18 @@ func (p *Parser) Parse(files []parser.ExtractedFile) (*models.AnalysisResult, er
|
||||
// Parse SEL list (selelist.csv), falling back to log/sel.csv on the
|
||||
// dump_<serial>_<timestamp>/ layout that has no selelist.csv.
|
||||
if f := parser.FindFileByName(files, "selelist.csv"); f != nil {
|
||||
selEvents := ParseSELListWithLocation(f.Content, selLocation)
|
||||
selEvents := parseSELListWithResolver(f.Content, selTimezone)
|
||||
result.Events = append(result.Events, selEvents...)
|
||||
} else if f := parser.FindFileByName(files, "sel.csv"); f != nil {
|
||||
selEvents := ParseSELListWithLocation(f.Content, selLocation)
|
||||
selEvents := parseSELListWithResolver(f.Content, selTimezone)
|
||||
result.Events = append(result.Events, selEvents...)
|
||||
}
|
||||
|
||||
// Parse syslog files
|
||||
syslogFiles := parser.FindFileByPattern(files, "syslog/alert", "syslog/warning", "syslog/notice", "syslog/info")
|
||||
syslogFiles := parser.FindFileByPattern(files,
|
||||
"syslog/emerg", "syslog/alert", "syslog/crit", "syslog/error",
|
||||
"syslog/warning", "syslog/notice", "syslog/info",
|
||||
)
|
||||
for _, f := range syslogFiles {
|
||||
events := ParseSyslog(f.Content, f.Path)
|
||||
result.Events = append(result.Events, events...)
|
||||
@@ -257,9 +261,11 @@ func (p *Parser) Parse(files []parser.ExtractedFile) (*models.AnalysisResult, er
|
||||
// controller, switch VR/power, switch CPLD and slot presence failures.
|
||||
result.Events = append(result.Events, ParseCommerCompEvents(files, selLocation)...)
|
||||
|
||||
// Same SEL event can be reported twice by the BMC (e.g. once via sel.csv,
|
||||
// once via idl.log); collapse exact duplicates so they don't double-count.
|
||||
// Same event can be reported by both IDL and SEL. After timezone
|
||||
// normalization, retain the richer offset-bearing IDL event and remove the
|
||||
// equivalent SEL copy, then provide a deterministic chronological stream.
|
||||
result.Events = dedupSELEvents(result.Events)
|
||||
sortInspurEvents(result.Events)
|
||||
|
||||
// Fallback for archives where board serial is missing in parsed FRU/asset data:
|
||||
// recover it from log content, never from archive filename.
|
||||
@@ -284,6 +290,13 @@ func (p *Parser) Parse(files []parser.ExtractedFile) (*models.AnalysisResult, er
|
||||
// Mark problematic GPUs from IDL errors like "BIOS miss F_GPU6".
|
||||
if result.Hardware != nil {
|
||||
applyGPUStatusFromEvents(result.Hardware, result.Events)
|
||||
var currentDeviceEvents []models.Event
|
||||
currentDeviceSnapshotAvailable := false
|
||||
if f := parser.FindFileByName(files, "dev_status.log"); f != nil {
|
||||
currentDeviceSnapshotAvailable = true
|
||||
currentDeviceEvents = ParseIDLLog(f.Content)
|
||||
}
|
||||
applyStorageStatusFromEvents(result.Hardware, result.Events, currentDeviceEvents, currentDeviceSnapshotAvailable)
|
||||
enrichStorageFromSerialFallbackFiles(files, result.Hardware)
|
||||
// Enrich storage serial numbers from smartd output in SOLHostCapture.log.
|
||||
// Fills in serial, model, firmware for backplane slots that the BMC HDD API left empty.
|
||||
|
||||
Reference in New Issue
Block a user