package artifacts import ( "context" "encoding/json" "fmt" "html/template" "sort" "strings" "time" "github.com/pkg/errors" analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze" "gopkg.in/yaml.v2" ) // JSONFormatter formats analysis results as JSON type JSONFormatter struct{} func (f *JSONFormatter) Format(ctx context.Context, result *analyzer.AnalysisResult) ([]byte, error) { return json.MarshalIndent(result, "", " ") } func (f *JSONFormatter) ContentType() string { return "application/json" } func (f *JSONFormatter) FileExtension() string { return "json" } // YAMLFormatter formats analysis results as YAML type YAMLFormatter struct{} func (f *YAMLFormatter) Format(ctx context.Context, result *analyzer.AnalysisResult) ([]byte, error) { return yaml.Marshal(result) } func (f *YAMLFormatter) ContentType() string { return "application/x-yaml" } func (f *YAMLFormatter) FileExtension() string { return "yaml" } // HTMLFormatter formats analysis results as HTML type HTMLFormatter struct{} func (f *HTMLFormatter) Format(ctx context.Context, result *analyzer.AnalysisResult) ([]byte, error) { tmpl := template.New("analysis").Funcs(template.FuncMap{ "formatTime": func(t time.Time) string { return t.Format("2006-01-02 15:04:05") }, "statusIcon": func(r *analyzer.AnalyzerResult) string { if r.IsPass { return "✅" } else if r.IsWarn { return "⚠️" } else if r.IsFail { return "❌" } return "❓" }, "statusClass": func(r *analyzer.AnalyzerResult) string { if r.IsPass { return "success" } else if r.IsWarn { return "warning" } else if r.IsFail { return "danger" } return "info" }, "priorityBadge": func(priority int) string { if priority >= 8 { return "badge-danger" } else if priority >= 5 { return "badge-warning" } return "badge-info" }, "truncate": func(s string, length int) string { if len(s) <= length { return s } return s[:length] + "..." }, "mul": func(a, b float64) float64 { return a * b }, }) htmlTemplate := `
Generated on {{formatTime .Metadata.Timestamp}} | Engine Version {{.Metadata.EngineVersion}}
Passed
Warnings
Failed
Total Analyzers
| Status | Title | Category | Agent | Confidence | Message |
|---|---|---|---|---|---|
| {{statusIcon .}} | {{.Title}} | {{.Category}} | {{.AgentName}} | {{if .Confidence}}{{printf "%.1f%%" (mul .Confidence 100)}}{{else}}-{{end}} | {{truncate .Message 100}} |
Duration: {{.Summary.Duration}}
{{if .Summary.Confidence}}Confidence: {{printf "%.1f%%" (mul .Summary.Confidence 100)}}
{{end}}Agents: {{len .Summary.AgentsUsed}}
Errors: {{len .Errors}}
{{.Command}}
{{.Description}}
Confidence: {{printf "%.1f%%" (mul .Confidence 100)}}