feat(hpe-ilo): parse AHS files, fix event logs export, add logs CSV export

- HPE iLO AHS parser: handle truncated last entry gracefully, recognize
  Alletra product line, expand event type/severity inference, trim iLO
  frame separators from event messages
- Fix event_logs always 0 in Reanimator export: normalizeEventLogSource
  now maps "HPE iLO" → "bmc"
- Fix chart JS not loading in LOGPile: rewriteChartStaticPaths now also
  rewrites src="/static/view.js" → /chart/static/view.js
- Add "Logs Export" button (CSV, semicolon-delimited, UTF-8 BOM) and
  remove PDF button
- Fix collector test broken by pciids rename of Intel VMD device
- Update submodules: chart v2.7, pciids, bible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-06-19 15:11:46 +03:00
parent cd864c3d6c
commit 3e3c48bc08
14 changed files with 2190 additions and 777 deletions

View File

@@ -174,3 +174,42 @@ func firstNonEmptyString(values ...string) string {
}
return ""
}
// ExportLogsCSV writes all recognized events as a semicolon-delimited UTF-8 CSV readable in Excel.
func ExportLogsCSV(w io.Writer, result *models.AnalysisResult) error {
if _, err := w.Write([]byte{0xEF, 0xBB, 0xBF}); err != nil {
return err
}
writer := csv.NewWriter(w)
writer.Comma = ';'
defer writer.Flush()
if err := writer.Write([]string{"timestamp", "source", "severity", "sensor_type", "sensor_name", "event_type", "id", "description", "raw_data"}); err != nil {
return err
}
if result == nil {
return nil
}
for _, e := range result.Events {
ts := ""
if !e.Timestamp.IsZero() {
ts = e.Timestamp.UTC().Format("2006-01-02T15:04:05Z")
}
if err := writer.Write([]string{
ts,
e.Source,
string(e.Severity),
e.SensorType,
e.SensorName,
e.EventType,
e.ID,
e.Description,
e.RawData,
}); err != nil {
return err
}
}
return nil
}

View File

@@ -1235,7 +1235,7 @@ func normalizeEventLogSource(source string) string {
switch strings.ToLower(strings.TrimSpace(source)) {
case "redfish":
return "redfish"
case "sel", "bmc", "ipmi", "idrac", "lifecycle controller", "lifecyclecontroller":
case "sel", "bmc", "ipmi", "idrac", "lifecycle controller", "lifecyclecontroller", "hpe ilo", "ilo":
return "bmc"
case "system", "syslog", "smart", "zfs", "file", "gpu", "dmi", "nvidia driver", "gpu field diagnostics", "fan", "memory", "host":
return "host"