feat(builder): log build failure output as separate lines
Log each line of build failure output as a separate structured log entry at WARN level, making output readable and queryable in Loki/Grafana. Add repo and rev fields to all build-related log entries. Add truncateOutputLines helper that returns a []string for per-line logging. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,23 @@ import (
|
||||
// Allows: alphanumeric, dashes, underscores, dots.
|
||||
var hostnameRegex = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`)
|
||||
|
||||
// truncateOutputLines truncates output to the first and last N lines if it exceeds 2*N lines,
|
||||
// returning the result as a slice of strings.
|
||||
func truncateOutputLines(output string, keepLines int) []string {
|
||||
lines := strings.Split(output, "\n")
|
||||
if len(lines) <= keepLines*2 {
|
||||
return lines
|
||||
}
|
||||
head := lines[:keepLines]
|
||||
tail := lines[len(lines)-keepLines:]
|
||||
omitted := len(lines) - keepLines*2
|
||||
result := make([]string, 0, keepLines*2+1)
|
||||
result = append(result, head...)
|
||||
result = append(result, fmt.Sprintf("... (%d lines omitted) ...", omitted))
|
||||
result = append(result, tail...)
|
||||
return result
|
||||
}
|
||||
|
||||
// truncateOutput truncates output to the first and last N lines if it exceeds 2*N lines.
|
||||
func truncateOutput(output string, keepLines int) string {
|
||||
lines := strings.Split(output, "\n")
|
||||
@@ -256,6 +273,8 @@ func (b *Builder) handleBuildRequest(subject string, data []byte) {
|
||||
hostStart := time.Now()
|
||||
b.logger.Info("building host",
|
||||
"host", host,
|
||||
"repo", req.Repo,
|
||||
"rev", branch,
|
||||
"progress", fmt.Sprintf("%d/%d", i+1, len(hosts)),
|
||||
"command", b.executor.BuildCommand(repo.URL, branch, host),
|
||||
)
|
||||
@@ -280,13 +299,18 @@ func (b *Builder) handleBuildRequest(subject string, data []byte) {
|
||||
|
||||
if result.Success {
|
||||
succeeded++
|
||||
b.logger.Info("host build succeeded", "host", host, "duration", hostDuration)
|
||||
b.logger.Info("host build succeeded", "host", host, "repo", req.Repo, "rev", branch, "duration", hostDuration)
|
||||
if b.metrics != nil {
|
||||
b.metrics.RecordHostBuildSuccess(req.Repo, host, hostDuration)
|
||||
}
|
||||
} else {
|
||||
failed++
|
||||
b.logger.Error("host build failed", "host", host, "error", hostResult.Error, "output", hostResult.Output)
|
||||
b.logger.Error("host build failed", "host", host, "repo", req.Repo, "rev", branch, "error", hostResult.Error)
|
||||
if result.Stderr != "" {
|
||||
for _, line := range truncateOutputLines(result.Stderr, 50) {
|
||||
b.logger.Warn("build output", "host", host, "repo", req.Repo, "line", line)
|
||||
}
|
||||
}
|
||||
if b.metrics != nil {
|
||||
b.metrics.RecordHostBuildFailure(req.Repo, host, hostDuration)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user