-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.go
82 lines (70 loc) · 2.11 KB
/
build.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package main
import (
"context"
"fmt"
"log"
"github.com/buildkite/go-buildkite/v3/buildkite"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
)
func (d *daemon) processBuild(ctx context.Context, b buildkite.Build) {
defer d.wg.Done()
log.Printf("processing build %d finished at %s", *b.Number, b.FinishedAt)
if b.StartedAt == nil || b.FinishedAt == nil {
return
}
// create build span
buildCtx, buildSpan := d.tracer.Start(ctx, fmt.Sprintf("%d", *b.Number), trace.WithTimestamp(b.StartedAt.Time))
// build timing
// reference: https://buildkite.com/docs/apis/rest-api/builds#timestamp-attributes
if b.ScheduledAt != nil {
buildSpan.SetAttributes(attribute.Int64("schedule_duration_ms", b.CreatedAt.Time.Sub(b.ScheduledAt.Time).Milliseconds()))
buildSpan.SetAttributes(attribute.Int64("create_duration_ms", b.StartedAt.Time.Sub(b.CreatedAt.Time).Milliseconds()))
}
// build state
if b.State != nil {
buildSpan.SetAttributes(attribute.String("state", *b.State))
switch *b.State {
case "failed":
buildSpan.SetStatus(codes.Error, *b.State)
case "passed", "finished":
buildSpan.SetStatus(codes.Ok, *b.State)
default:
buildSpan.SetStatus(codes.Unset, *b.State)
}
}
// build metadata
if b.Commit != nil {
buildSpan.SetAttributes(attribute.String("commit", *b.Commit))
}
if b.Branch != nil {
buildSpan.SetAttributes(attribute.String("branch", *b.Branch))
}
if b.Author != nil {
buildSpan.SetAttributes(attribute.String("author", b.Author.Email))
}
if b.WebURL != nil {
buildSpan.SetAttributes(attribute.String("url", *b.WebURL))
}
// TODO: allow filtering metadata keys
if b.MetaData != nil {
switch m := b.MetaData.(type) {
// this cannot be casted directly to map[string]string
case map[string]interface{}:
for k, v := range m {
switch val := v.(type) {
case string:
buildSpan.SetAttributes(attribute.String("build_"+k, val))
default:
}
}
default:
}
}
// create job spans
for _, j := range b.Jobs {
d.processJob(buildCtx, *b.ID, j)
}
buildSpan.End(trace.WithTimestamp(b.FinishedAt.Time))
}