sync file-type support across upload/convert and fix collected_at timezone handling

This commit is contained in:
2026-02-28 23:27:49 +03:00
parent 736b77f055
commit 4940cd9645
20 changed files with 931 additions and 49 deletions

View File

@@ -3,14 +3,33 @@
package nvidia_bug_report
import (
"fmt"
"regexp"
"strings"
"time"
"git.mchus.pro/mchus/logpile/internal/models"
"git.mchus.pro/mchus/logpile/internal/parser"
)
// parserVersion - version of this parser module
const parserVersion = "1.0.0"
const parserVersion = "1.1.0"
var bugReportDateLineRegex = regexp.MustCompile(`(?m)^Date:\s+(.+?)\s*$`)
var dateWithTZAbbrevRegex = regexp.MustCompile(`^([A-Za-z]{3}\s+[A-Za-z]{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2})\s+([A-Za-z]{2,5})\s+(\d{4})$`)
var timezoneAbbrevToOffset = map[string]string{
"UTC": "+00:00",
"GMT": "+00:00",
"EST": "-05:00",
"EDT": "-04:00",
"CST": "-06:00",
"CDT": "-05:00",
"MST": "-07:00",
"MDT": "-06:00",
"PST": "-08:00",
"PDT": "-07:00",
}
func init() {
parser.Register(&Parser{})
@@ -81,6 +100,10 @@ func (p *Parser) Parse(files []parser.ExtractedFile) (*models.AnalysisResult, er
}
content := string(files[0].Content)
if collectedAt, tzOffset, ok := parseBugReportCollectedAt(content); ok {
result.CollectedAt = collectedAt.UTC()
result.SourceTimezone = tzOffset
}
// Parse system information
parseSystemInfo(content, result)
@@ -105,3 +128,49 @@ func (p *Parser) Parse(files []parser.ExtractedFile) (*models.AnalysisResult, er
return result, nil
}
func parseBugReportCollectedAt(content string) (time.Time, string, bool) {
matches := bugReportDateLineRegex.FindStringSubmatch(content)
if len(matches) != 2 {
return time.Time{}, "", false
}
raw := strings.TrimSpace(matches[1])
if raw == "" {
return time.Time{}, "", false
}
if m := dateWithTZAbbrevRegex.FindStringSubmatch(raw); len(m) == 4 {
if offset, ok := timezoneAbbrevToOffset[strings.ToUpper(strings.TrimSpace(m[2]))]; ok {
layout := "Mon Jan 2 15:04:05 -07:00 2006"
normalized := strings.TrimSpace(m[1]) + " " + offset + " " + strings.TrimSpace(m[3])
if ts, err := time.Parse(layout, normalized); err == nil {
return ts, offset, true
}
}
}
layouts := []string{
"Mon Jan 2 15:04:05 MST 2006",
"Mon Jan 2 15:04:05 2006",
}
for _, layout := range layouts {
ts, err := time.Parse(layout, raw)
if err != nil {
continue
}
return ts, formatOffset(ts), true
}
return time.Time{}, "", false
}
func formatOffset(t time.Time) string {
_, sec := t.Zone()
sign := '+'
if sec < 0 {
sign = '-'
sec = -sec
}
h := sec / 3600
m := (sec % 3600) / 60
return fmt.Sprintf("%c%02d:%02d", sign, h, m)
}

View File

@@ -0,0 +1,54 @@
package nvidia_bug_report
import (
"testing"
"time"
"git.mchus.pro/mchus/logpile/internal/parser"
)
func TestParseBugReportCollectedAt(t *testing.T) {
content := `
Start of NVIDIA bug report log file
Date: Fri Dec 12 10:14:49 EST 2025
`
got, tz, ok := parseBugReportCollectedAt(content)
if !ok {
t.Fatalf("expected collected_at to be parsed")
}
if tz != "-05:00" {
t.Fatalf("expected tz offset -05:00, got %q", tz)
}
wantUTC := time.Date(2025, 12, 12, 15, 14, 49, 0, time.UTC)
if !got.UTC().Equal(wantUTC) {
t.Fatalf("expected %s, got %s", wantUTC, got.UTC())
}
}
func TestNvidiaBugReportParser_SetsCollectedAtAndTimezone(t *testing.T) {
p := &Parser{}
files := []parser.ExtractedFile{
{
Path: "nvidia-bug-report-1653925023938.log",
Content: []byte(`
Start of NVIDIA bug report log file
nvidia-bug-report.sh Version: 34275561
Date: Fri Dec 12 10:14:49 EST 2025
`),
},
}
result, err := p.Parse(files)
if err != nil {
t.Fatalf("parse failed: %v", err)
}
if result.SourceTimezone != "-05:00" {
t.Fatalf("expected source timezone -05:00, got %q", result.SourceTimezone)
}
wantUTC := time.Date(2025, 12, 12, 15, 14, 49, 0, time.UTC)
if !result.CollectedAt.Equal(wantUTC) {
t.Fatalf("expected collected_at %s, got %s", wantUTC, result.CollectedAt)
}
}