package main import ( "encoding/json" "fmt" "os" "sync" "time" ) type LogWriter struct { file *os.File mu sync.Mutex errorsOnly bool } func NewLogWriter(path string, errorsOnly bool) (*LogWriter, error) { f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { return nil, err } return &LogWriter{file: f, errorsOnly: errorsOnly}, nil } func (lw *LogWriter) Write(line string, isError bool) { if lw.errorsOnly && !isError { return } lw.mu.Lock() defer lw.mu.Unlock() fmt.Fprintln(lw.file, line) } func (lw *LogWriter) Close() error { return lw.file.Close() } func writeStats(stats *Stats) { finishedAt := time.Now() duration := finishedAt.Sub(stats.StartedAt) data := map[string]interface{}{ "started_at": stats.StartedAt.Format(time.RFC3339), "finished_at": finishedAt.Format(time.RFC3339), "duration_seconds": int(duration.Seconds()), "total_hosts": stats.TotalHosts, "hosts_with_icon": stats.HostsWithIcon, "hosts_no_icon": stats.HostsNoIcon, "convert_errors": stats.ConvertErrors.Load(), "bundles_created": stats.BundlesCreated, "total_bytes": stats.TotalBytes, } os.MkdirAll("stats", 0755) f, err := os.Create("stats/05_bundle_gen.json") if err != nil { fmt.Printf("Failed to write stats: %v\n", err) return } defer f.Close() enc := json.NewEncoder(f) enc.SetIndent("", " ") enc.Encode(data) fmt.Println("Stats written to stats/05_bundle_gen.json") }