chore: align codebase with bible engineering contracts

- identifier-normalization: use strings.EqualFold in h3c/parser.go
- import-export: CSV now uses UTF-8 BOM and semicolon delimiter
- go-code-style: translate all Russian source strings to English (ADL-007)
- go-background-tasks: add Type, Message, Result fields to Job struct
- go-api: wrap list endpoints in {items, total_count, page, per_page, total_pages}
- module-structure: rename helpers.go → context_sleep.go
- build-version-display: htmlError renders version footer on error pages
- go-logging: migrate all log.Printf calls to log/slog with structured attrs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 14:35:39 +03:00
parent 47ff1c3796
commit 57de3ba6eb
14 changed files with 259 additions and 199 deletions
+3 -3
View File
@@ -19,9 +19,9 @@ func (c *IPMIMockConnector) Protocol() string {
func (c *IPMIMockConnector) Collect(ctx context.Context, req Request, emit ProgressFn) (*models.AnalysisResult, error) {
steps := []Progress{
{Status: "running", Progress: 20, Message: "IPMI: подключение к BMC..."},
{Status: "running", Progress: 55, Message: "IPMI: чтение инвентаря..."},
{Status: "running", Progress: 85, Message: "IPMI: нормализация данных..."},
{Status: "running", Progress: 20, Message: "IPMI: connecting to BMC..."},
{Status: "running", Progress: 55, Message: "IPMI: reading inventory..."},
{Status: "running", Progress: 85, Message: "IPMI: normalizing data..."},
}
for _, step := range steps {
+81 -86
View File
@@ -6,7 +6,7 @@ import (
"encoding/json"
"fmt"
"io"
"log"
"log/slog"
"net/http"
"net/url"
"os"
@@ -124,14 +124,14 @@ func (c *RedfishConnector) debugf(format string, args ...interface{}) {
if !c.debug {
return
}
log.Printf("redfish-debug: "+format, args...)
slog.Debug("redfish-debug: " + fmt.Sprintf(format, args...))
}
func (c *RedfishConnector) debugSnapshotf(format string, args ...interface{}) {
if !c.debugSnapshot {
return
}
log.Printf("redfish-snapshot-debug: "+format, args...)
slog.Debug("redfish-snapshot-debug: " + fmt.Sprintf(format, args...))
}
func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit ProgressFn) (*models.AnalysisResult, error) {
@@ -149,7 +149,7 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
hintClient := c.httpClientWithTimeout(req, 4*time.Second)
if emit != nil {
emit(Progress{Status: "running", Progress: 10, Message: "Redfish: подключение к BMC..."})
emit(Progress{Status: "running", Progress: 10, Message: "Redfish: connecting to BMC..."})
}
discoveryCtx := withRedfishTelemetryPhase(ctx, "discovery")
serviceRootDoc, err := c.getJSON(discoveryCtx, snapshotClient, req, baseURL, "/redfish/v1")
@@ -192,7 +192,7 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
emit(Progress{
Status: "running",
Progress: 25,
Message: fmt.Sprintf("Redfish: профили mode=%s active=%s", acquisitionPlan.Mode, formatActiveModuleLog(activeModules)),
Message: fmt.Sprintf("Redfish: profiles mode=%s active=%s", acquisitionPlan.Mode, formatActiveModuleLog(activeModules)),
ActiveModules: activeModules,
ModuleScores: moduleScores,
DebugInfo: &CollectDebugInfo{
@@ -229,33 +229,32 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
seedPaths := resolvedPlan.SeedPaths
criticalPaths := resolvedPlan.CriticalPaths
if len(acquisitionPlan.Profiles) > 0 {
log.Printf(
"redfish-profile-plan: mode=%s profiles=%s notes=%s scores=%s req=%d err=%d p95=%dms avg=%dms throttled=%t",
acquisitionPlan.Mode,
strings.Join(acquisitionPlan.Profiles, ","),
strings.Join(acquisitionPlan.Notes, "; "),
formatModuleScoreLog(moduleScores),
telemetrySummary.Requests,
telemetrySummary.Errors,
telemetrySummary.P95.Milliseconds(),
telemetrySummary.Avg.Milliseconds(),
throttled,
slog.Info("redfish-profile-plan",
"mode", acquisitionPlan.Mode,
"profiles", strings.Join(acquisitionPlan.Profiles, ","),
"notes", strings.Join(acquisitionPlan.Notes, "; "),
"scores", formatModuleScoreLog(moduleScores),
"req", telemetrySummary.Requests,
"err", telemetrySummary.Errors,
"p95_ms", telemetrySummary.P95.Milliseconds(),
"avg_ms", telemetrySummary.Avg.Milliseconds(),
"throttled", throttled,
)
}
if emit != nil {
emit(Progress{
Status: "running",
Progress: 30,
Message: "Redfish: чтение структуры Redfish...",
Message: "Redfish: reading Redfish structure...",
CurrentPhase: "snapshot",
ETASeconds: acquisitionPlan.Tuning.ETABaseline.SnapshotSeconds,
})
}
if emit != nil {
emit(Progress{Status: "running", Progress: 55, Message: "Redfish: подготовка snapshot...", CurrentPhase: "snapshot", ETASeconds: acquisitionPlan.Tuning.ETABaseline.SnapshotSeconds})
emit(Progress{Status: "running", Progress: 80, Message: "Redfish: подготовка расширенного snapshot...", CurrentPhase: "snapshot", ETASeconds: acquisitionPlan.Tuning.ETABaseline.SnapshotSeconds})
emit(Progress{Status: "running", Progress: 90, Message: "Redfish: сбор расширенного snapshot...", CurrentPhase: "snapshot", ETASeconds: acquisitionPlan.Tuning.ETABaseline.SnapshotSeconds})
emit(Progress{Status: "running", Progress: 55, Message: "Redfish: preparing snapshot...", CurrentPhase: "snapshot", ETASeconds: acquisitionPlan.Tuning.ETABaseline.SnapshotSeconds})
emit(Progress{Status: "running", Progress: 80, Message: "Redfish: preparing extended snapshot...", CurrentPhase: "snapshot", ETASeconds: acquisitionPlan.Tuning.ETABaseline.SnapshotSeconds})
emit(Progress{Status: "running", Progress: 90, Message: "Redfish: collecting extended snapshot...", CurrentPhase: "snapshot", ETASeconds: acquisitionPlan.Tuning.ETABaseline.SnapshotSeconds})
}
// collectCtx covers all data-fetching phases (snapshot, prefetch, plan-B).
// Cancelling it via the skip signal aborts only the collection phases while
@@ -270,10 +269,10 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
emit(Progress{
Status: "running",
Progress: 97,
Message: "Redfish: пропуск зависших запросов, анализ уже собранных данных...",
Message: "Redfish: skipping stalled requests, analyzing collected data...",
})
}
log.Printf("redfish: skip-hung triggered, cancelling collection phases")
slog.Info("redfish: skip-hung triggered, cancelling collection phases")
cancelCollect()
case <-ctx.Done():
}
@@ -296,15 +295,14 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
for p := range prefetchedCritical {
delete(fetchErrMap, p)
}
log.Printf(
"redfish-prefetch-metrics: enabled=%t candidates=%d targets=%d docs=%d added=%d dur=%s skip=%s",
prefetchMetrics.Enabled,
prefetchMetrics.Candidates,
prefetchMetrics.Targets,
prefetchMetrics.Docs,
prefetchMetrics.Added,
prefetchMetrics.Duration.Round(time.Millisecond),
firstNonEmpty(prefetchMetrics.SkipReason, "-"),
slog.Info("redfish-prefetch-metrics",
"enabled", prefetchMetrics.Enabled,
"candidates", prefetchMetrics.Candidates,
"targets", prefetchMetrics.Targets,
"docs", prefetchMetrics.Docs,
"added", prefetchMetrics.Added,
"dur", prefetchMetrics.Duration.Round(time.Millisecond),
"skip", firstNonEmpty(prefetchMetrics.SkipReason, "-"),
)
if recoveredN := c.recoverCriticalRedfishDocsPlanB(withRedfishTelemetryPhase(collectCtx, "critical_plan_b"), criticalClient, req, baseURL, criticalPaths, rawTree, fetchErrMap, acquisitionPlan.Tuning, emit); recoveredN > 0 {
c.debugSnapshotf("critical plan-b recovered docs=%d", recoveredN)
@@ -319,7 +317,7 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
}
}
if emit != nil {
emit(Progress{Status: "running", Progress: 99, Message: "Redfish: анализ raw snapshot..."})
emit(Progress{Status: "running", Progress: 99, Message: "Redfish: analyzing raw snapshot..."})
}
// Collect hardware event logs separately (not part of tree-walk to avoid bloat).
rawLogEntries := c.collectRedfishLogEntries(withRedfishTelemetryPhase(ctx, "log_entries"), snapshotClient, req, baseURL, systemPaths, managerPaths)
@@ -443,38 +441,36 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
}
totalElapsed := time.Since(collectStart).Round(time.Second)
if !result.InventoryLastModifiedAt.IsZero() {
log.Printf("redfish-collect: inventory last modified at %s (age: %s)",
result.InventoryLastModifiedAt.Format(time.RFC3339),
time.Since(result.InventoryLastModifiedAt).Round(time.Minute),
slog.Info("redfish-collect: inventory last modified",
"at", result.InventoryLastModifiedAt.Format(time.RFC3339),
"age", time.Since(result.InventoryLastModifiedAt).Round(time.Minute),
)
}
log.Printf(
"redfish-postprobe-metrics: nvme_candidates=%d nvme_selected=%d nvme_added=%d candidates=%d selected=%d skipped_explicit=%d added=%d dur=%s",
postProbeMetrics.NVMECandidates,
postProbeMetrics.NVMESelected,
postProbeMetrics.NVMEAdded,
postProbeMetrics.CollectionCandidates,
postProbeMetrics.CollectionSelected,
postProbeMetrics.SkippedExplicit,
postProbeMetrics.Added,
postProbeMetrics.Duration.Round(time.Millisecond),
slog.Info("redfish-postprobe-metrics",
"nvme_candidates", postProbeMetrics.NVMECandidates,
"nvme_selected", postProbeMetrics.NVMESelected,
"nvme_added", postProbeMetrics.NVMEAdded,
"candidates", postProbeMetrics.CollectionCandidates,
"selected", postProbeMetrics.CollectionSelected,
"skipped_explicit", postProbeMetrics.SkippedExplicit,
"added", postProbeMetrics.Added,
"dur", postProbeMetrics.Duration.Round(time.Millisecond),
)
log.Printf(
"redfish-telemetry: req=%d err=%d err_rate=%.2f avg=%dms p95=%dms throttled=%t snapshot_workers=%d prefetch_workers=%d timing_top=%s",
telemetrySummary.Requests,
telemetrySummary.Errors,
telemetrySummary.ErrorRate,
telemetrySummary.Avg.Milliseconds(),
telemetrySummary.P95.Milliseconds(),
throttled,
acquisitionPlan.Tuning.SnapshotWorkers,
acquisitionPlan.Tuning.PrefetchWorkers,
firstNonEmpty(snapshotTimingSummary, "-"),
slog.Info("redfish-telemetry",
"req", telemetrySummary.Requests,
"err", telemetrySummary.Errors,
"err_rate", telemetrySummary.ErrorRate,
"avg_ms", telemetrySummary.Avg.Milliseconds(),
"p95_ms", telemetrySummary.P95.Milliseconds(),
"throttled", throttled,
"snapshot_workers", acquisitionPlan.Tuning.SnapshotWorkers,
"prefetch_workers", acquisitionPlan.Tuning.PrefetchWorkers,
"timing_top", firstNonEmpty(snapshotTimingSummary, "-"),
)
for _, line := range redfishPhaseTelemetryLogLines(phaseTelemetry) {
log.Printf("redfish-telemetry-phase: %s", line)
slog.Info("redfish-telemetry-phase", "line", line)
}
log.Printf("redfish-collect: completed in %s (docs=%d, fetch_errors=%d)", totalElapsed, len(rawTree), len(fetchErrMap))
slog.Info("redfish-collect: completed", "elapsed", totalElapsed, "docs", len(rawTree), "fetch_errors", len(fetchErrMap))
if emit != nil {
emit(Progress{
Status: "running",
@@ -491,7 +487,7 @@ func (c *RedfishConnector) Collect(ctx context.Context, req Request, emit Progre
emit(Progress{
Status: "running",
Progress: 100,
Message: fmt.Sprintf("Redfish: сбор завершен за %s", totalElapsed),
Message: fmt.Sprintf("Redfish: collection completed in %s", totalElapsed),
})
}
return result, nil
@@ -611,7 +607,7 @@ func (c *RedfishConnector) prefetchCriticalRedfishDocs(
emit(Progress{
Status: "running",
Progress: 96,
Message: fmt.Sprintf("Redfish: prefetch пропущен (адаптивно, кандидатов=%d)", metrics.Candidates),
Message: fmt.Sprintf("Redfish: prefetch skipped (adaptive, candidates=%d)", metrics.Candidates),
})
}
return nil, metrics
@@ -620,7 +616,7 @@ func (c *RedfishConnector) prefetchCriticalRedfishDocs(
emit(Progress{
Status: "running",
Progress: 96,
Message: fmt.Sprintf("Redfish: prefetch критичных endpoint (адаптивно %d/%d)...", len(targets), len(candidates)),
Message: fmt.Sprintf("Redfish: prefetch critical endpoints (adaptive %d/%d)...", len(targets), len(candidates)),
CurrentPhase: "prefetch",
ETASeconds: int(estimateProgressETA(time.Now(), 0, len(targets), 2*time.Second).Seconds()),
})
@@ -706,7 +702,7 @@ func (c *RedfishConnector) prefetchCriticalRedfishDocs(
emit(Progress{
Status: "running",
Progress: 96,
Message: fmt.Sprintf("Redfish: prefetch завершен (адаптивно targets=%d, docs=%d)", len(targets), len(out)),
Message: fmt.Sprintf("Redfish: prefetch completed (adaptive targets=%d, docs=%d)", len(targets), len(out)),
CurrentPhase: "prefetch",
})
}
@@ -1397,7 +1393,7 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 92 + int(minInt32(n/200, 6)),
Message: fmt.Sprintf("Redfish snapshot: heartbeat документов=%d (ok=%d, seen=%d), ETA≈%s, корни=%s, последний=%s", n, outN, seenN, eta, strings.Join(roots, ", "), compactProgressPath(last)),
Message: fmt.Sprintf("Redfish snapshot: heartbeat docs=%d (ok=%d, seen=%d), ETA≈%s, roots=%s, last=%s", n, outN, seenN, eta, strings.Join(roots, ", "), compactProgressPath(last)),
CurrentPhase: "snapshot",
ETASeconds: int(estimateSnapshotETA(crawlStart, int(n), seenN, len(jobs), workers, client.Timeout).Seconds()),
})
@@ -1434,7 +1430,7 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 92 + int(minInt32(n/200, 6)),
Message: fmt.Sprintf("Redfish snapshot: ошибка на %s", compactProgressPath(current)),
Message: fmt.Sprintf("Redfish snapshot: error on %s", compactProgressPath(current)),
})
}
wg.Done()
@@ -1489,7 +1485,7 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 92 + int(minInt32(n/200, 6)),
Message: fmt.Sprintf("Redfish snapshot: ошибка на %s", compactProgressPath(current)),
Message: fmt.Sprintf("Redfish snapshot: error on %s", compactProgressPath(current)),
})
}
}
@@ -1512,7 +1508,7 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 92 + int(minInt32(n/200, 6)),
Message: fmt.Sprintf("Redfish snapshot: документов=%d, ETA≈%s, корни=%s, последний=%s", n, eta, strings.Join(roots, ", "), compactProgressPath(last)),
Message: fmt.Sprintf("Redfish snapshot: docs=%d, ETA≈%s, roots=%s, last=%s", n, eta, strings.Join(roots, ", "), compactProgressPath(last)),
CurrentPhase: "snapshot",
ETASeconds: int(estimateSnapshotETA(crawlStart, int(n), seenN, len(jobs), workers, client.Timeout).Seconds()),
})
@@ -1574,7 +1570,7 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 97,
Message: fmt.Sprintf("Redfish snapshot: post-probe NVMe (%d/%d, ETA≈%s), коллекция=%s", i+1, len(driveCollections), formatETA(estimateProgressETA(nvmeProbeStart, i, len(driveCollections), 2*time.Second)), compactProgressPath(path)),
Message: fmt.Sprintf("Redfish snapshot: post-probe NVMe (%d/%d, ETA≈%s), collection=%s", i+1, len(driveCollections), formatETA(estimateProgressETA(nvmeProbeStart, i, len(driveCollections), 2*time.Second)), compactProgressPath(path)),
CurrentPhase: "snapshot_postprobe_nvme",
ETASeconds: int(estimateProgressETA(nvmeProbeStart, i, len(driveCollections), 2*time.Second).Seconds()),
})
@@ -1622,7 +1618,7 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 98,
Message: fmt.Sprintf("Redfish snapshot: post-probe коллекций (%d/%d, ETA≈%s), текущая=%s", i+1, len(postProbeCollections), formatETA(estimateProgressETA(postProbeStart, i, len(postProbeCollections), 3*time.Second)), compactProgressPath(path)),
Message: fmt.Sprintf("Redfish snapshot: post-probe collections (%d/%d, ETA≈%s), current=%s", i+1, len(postProbeCollections), formatETA(estimateProgressETA(postProbeStart, i, len(postProbeCollections), 3*time.Second)), compactProgressPath(path)),
CurrentPhase: "snapshot_postprobe_collections",
ETASeconds: int(estimateProgressETA(postProbeStart, i, len(postProbeCollections), 3*time.Second).Seconds()),
})
@@ -1641,14 +1637,14 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 98,
Message: fmt.Sprintf("Redfish snapshot: post-probe добавлено %d документов", addedPostProbe),
Message: fmt.Sprintf("Redfish snapshot: post-probe added %d docs", addedPostProbe),
})
}
if emit != nil {
emit(Progress{
Status: "running",
Progress: 98,
Message: fmt.Sprintf("Redfish snapshot: post-probe метрики candidates=%d selected=%d skipped_explicit=%d added=%d", postProbeMetrics.CollectionCandidates, postProbeMetrics.CollectionSelected, postProbeMetrics.SkippedExplicit, postProbeMetrics.Added),
Message: fmt.Sprintf("Redfish snapshot: post-probe metrics candidates=%d selected=%d skipped_explicit=%d added=%d", postProbeMetrics.CollectionCandidates, postProbeMetrics.CollectionSelected, postProbeMetrics.SkippedExplicit, postProbeMetrics.Added),
})
}
@@ -1656,7 +1652,7 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
emit(Progress{
Status: "running",
Progress: 98,
Message: fmt.Sprintf("Redfish snapshot: собрано %d документов", len(out)),
Message: fmt.Sprintf("Redfish snapshot: collected %d docs", len(out)),
})
}
@@ -1671,14 +1667,14 @@ func (c *RedfishConnector) collectRawRedfishTree(ctx context.Context, client *ht
return asString(errorList[i]["path"]) < asString(errorList[j]["path"])
})
if summary := timings.Summary(12); summary != "" {
log.Printf("redfish-snapshot-timing: %s", summary)
slog.Info("redfish-snapshot-timing", "summary", summary)
}
if emit != nil {
if summary := timings.Summary(3); summary != "" {
emit(Progress{
Status: "running",
Progress: 98,
Message: fmt.Sprintf("Redfish snapshot: топ веток по времени: %s", summary),
Message: fmt.Sprintf("Redfish snapshot: top branches by time: %s", summary),
})
}
}
@@ -2979,14 +2975,14 @@ func (c *RedfishConnector) recoverCriticalRedfishDocsPlanB(ctx context.Context,
emit(Progress{
Status: "running",
Progress: 97,
Message: fmt.Sprintf("Redfish: расширенная диагностика выключена, пропущено %d тяжелых diagnostic endpoint", skippedDiagnosticTargets),
Message: fmt.Sprintf("Redfish: extended diagnostics disabled, skipped %d heavy diagnostic endpoints", skippedDiagnosticTargets),
})
}
totalETA := redfishCriticalCooldown() + estimatePlanBETA(len(targets))
emit(Progress{
Status: "running",
Progress: 97,
Message: fmt.Sprintf("Redfish: cooldown перед повторным добором критичных endpoint... ETA≈%s", formatETA(totalETA)),
Message: fmt.Sprintf("Redfish: cooldown before retrying critical endpoints... ETA≈%s", formatETA(totalETA)),
CurrentPhase: "critical_plan_b",
ETASeconds: int(totalETA.Seconds()),
})
@@ -3072,17 +3068,17 @@ func (c *RedfishConnector) recoverCriticalRedfishDocsPlanB(ctx context.Context,
emit(Progress{
Status: "running",
Progress: 97,
Message: fmt.Sprintf("Redfish: plan-B топ веток по времени: %s", summary),
Message: fmt.Sprintf("Redfish: plan-B top branches by time: %s", summary),
})
}
emit(Progress{
Status: "running",
Progress: 97,
Message: fmt.Sprintf("Redfish: plan-B завершен за %s (targets=%d, recovered=%d)", time.Since(planBStart).Round(time.Second), len(targets), recovered),
Message: fmt.Sprintf("Redfish: plan-B completed in %s (targets=%d, recovered=%d)", time.Since(planBStart).Round(time.Second), len(targets), recovered),
})
}
if summary := timings.Summary(12); summary != "" {
log.Printf("redfish-planb-timing: %s", summary)
slog.Info("redfish-planb-timing", "summary", summary)
}
return recovered
}
@@ -3143,7 +3139,7 @@ func (c *RedfishConnector) recoverProfilePlanBDocs(ctx context.Context, client *
emit(Progress{
Status: "running",
Progress: 98,
Message: fmt.Sprintf("Redfish: profile plan-B добирает %d endpoint...", len(targets)),
Message: fmt.Sprintf("Redfish: profile plan-B fetching %d endpoints...", len(targets)),
CurrentPhase: "profile_plan_b",
ETASeconds: int(estimateProgressETA(planBStart, 0, len(targets), 2*time.Second).Seconds()),
})
@@ -3167,19 +3163,18 @@ func (c *RedfishConnector) recoverProfilePlanBDocs(ctx context.Context, client *
recovered++
}
if recovered > 0 {
log.Printf(
"redfish-profile-planb: mode=%s profiles=%s targets=%d recovered=%d",
plan.Mode,
strings.Join(plan.Profiles, ","),
len(targets),
recovered,
slog.Info("redfish-profile-planb",
"mode", plan.Mode,
"profiles", strings.Join(plan.Profiles, ","),
"targets", len(targets),
"recovered", recovered,
)
}
if emit != nil {
emit(Progress{
Status: "running",
Progress: 98,
Message: fmt.Sprintf("Redfish: profile plan-B завершен за %s (targets=%d, recovered=%d)", time.Since(planBStart).Round(time.Second), len(targets), recovered),
Message: fmt.Sprintf("Redfish: profile plan-B completed in %s (targets=%d, recovered=%d)", time.Since(planBStart).Round(time.Second), len(targets), recovered),
CurrentPhase: "profile_plan_b",
})
}
+2 -2
View File
@@ -2,7 +2,7 @@ package collector
import (
"context"
"log"
"log/slog"
"net/http"
"strings"
"time"
@@ -62,7 +62,7 @@ func (c *RedfishConnector) collectRedfishLogEntries(ctx context.Context, client
}
if len(out) > 0 {
log.Printf("redfish: collected %d hardware log entries (Systems+Managers SEL, window=7d)", len(out))
slog.Info("redfish: collected hardware log entries", "count", len(out), "window", "7d")
}
return out
}
+3 -3
View File
@@ -3,7 +3,7 @@ package collector
import (
"encoding/json"
"fmt"
"log"
"log/slog"
"sort"
"strings"
"time"
@@ -32,7 +32,7 @@ func ReplayRedfishFromRawPayloads(rawPayloads map[string]any, emit ProgressFn) (
emit(Progress{Status: "running", Progress: 10, Message: "Redfish snapshot: replay service root..."})
}
if _, err := r.getJSON("/redfish/v1"); err != nil {
log.Printf("redfish replay: service root /redfish/v1 missing from snapshot, continuing with defaults: %v", err)
slog.Warn("redfish replay: service root /redfish/v1 missing from snapshot, continuing with defaults", "err", err)
}
systemPaths := r.discoverMemberPaths("/redfish/v1/Systems", "/redfish/v1/Systems/1")
@@ -219,7 +219,7 @@ func inferInventoryLastModifiedTime(snapshot map[string]interface{}) time.Time {
for _, layout := range []string{time.RFC3339, time.RFC3339Nano} {
if ts, err := time.Parse(layout, raw); err == nil {
t := ts.UTC()
log.Printf("redfish replay: inventory last modified at %s (InventoryData/Status.LastModifiedTime)", t.Format(time.RFC3339))
slog.Info("redfish replay: inventory last modified", "at", t.Format(time.RFC3339), "source", "InventoryData/Status.LastModifiedTime")
return t
}
}