Add LOGPile BMC diagnostic log analyzer
Features: - Modular parser architecture for vendor-specific formats - Inspur/Kaytus parser supporting asset.json, devicefrusdr.log, component.log, idl.log, and syslog files - PCI Vendor/Device ID lookup for hardware identification - Web interface with tabs: Events, Sensors, Config, Serials, Firmware - Server specification summary with component grouping - Export to CSV, JSON, TXT formats - BMC alarm parsing from IDL logs (memory errors, PSU events, etc.) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
86
internal/parser/parser.go
Normal file
86
internal/parser/parser.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"git.mchus.pro/mchus/logpile/internal/models"
|
||||
)
|
||||
|
||||
// BMCParser parses BMC diagnostic archives using vendor-specific parsers
|
||||
type BMCParser struct {
|
||||
result *models.AnalysisResult
|
||||
files []ExtractedFile
|
||||
vendorParser VendorParser
|
||||
}
|
||||
|
||||
// NewBMCParser creates a new BMC parser
|
||||
func NewBMCParser() *BMCParser {
|
||||
return &BMCParser{
|
||||
result: &models.AnalysisResult{
|
||||
Events: make([]models.Event, 0),
|
||||
FRU: make([]models.FRUInfo, 0),
|
||||
Sensors: make([]models.SensorReading, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ParseArchive parses an archive file
|
||||
func (p *BMCParser) ParseArchive(archivePath string) error {
|
||||
files, err := ExtractArchive(archivePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("extract archive: %w", err)
|
||||
}
|
||||
p.files = files
|
||||
return p.parseFiles()
|
||||
}
|
||||
|
||||
// ParseFromReader parses archive from reader
|
||||
func (p *BMCParser) ParseFromReader(r io.Reader, filename string) error {
|
||||
files, err := ExtractArchiveFromReader(r, filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("extract archive: %w", err)
|
||||
}
|
||||
p.files = files
|
||||
p.result.Filename = filename
|
||||
return p.parseFiles()
|
||||
}
|
||||
|
||||
func (p *BMCParser) parseFiles() error {
|
||||
// Auto-detect format
|
||||
vendorParser, err := DetectFormat(p.files)
|
||||
if err != nil {
|
||||
return fmt.Errorf("detect format: %w", err)
|
||||
}
|
||||
p.vendorParser = vendorParser
|
||||
|
||||
// Parse using detected vendor parser
|
||||
result, err := vendorParser.Parse(p.files)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse with %s: %w", vendorParser.Name(), err)
|
||||
}
|
||||
|
||||
// Preserve filename
|
||||
result.Filename = p.result.Filename
|
||||
p.result = result
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Result returns the analysis result
|
||||
func (p *BMCParser) Result() *models.AnalysisResult {
|
||||
return p.result
|
||||
}
|
||||
|
||||
// GetFiles returns all extracted files
|
||||
func (p *BMCParser) GetFiles() []ExtractedFile {
|
||||
return p.files
|
||||
}
|
||||
|
||||
// DetectedVendor returns the detected vendor parser name
|
||||
func (p *BMCParser) DetectedVendor() string {
|
||||
if p.vendorParser != nil {
|
||||
return p.vendorParser.Name()
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
Reference in New Issue
Block a user