Skip to content

Commit

Permalink
Add segment reporter
Browse files Browse the repository at this point in the history
  • Loading branch information
csweichel committed Jul 3, 2023
1 parent dd76210 commit c3e7bac
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ func addBuildFlags(cmd *cobra.Command) {
cmd.Flags().String("coverage-output-path", "", "Output path where test coverage file will be copied after running tests")
cmd.Flags().StringToString("docker-build-options", nil, "Options passed to all 'docker build' commands")
cmd.Flags().String("report", "", "Generate a HTML report after the build has finished. (e.g. --report myreport.html)")
cmd.Flags().String("report-segment", os.Getenv("LEEWAY_SEGMENT_KEY"), "Report build events to segment using the segment key (defaults to $LEEWAY_SEGMENT_KEY)")
}

func getBuildOpts(cmd *cobra.Command) ([]leeway.BuildOption, *leeway.FilesystemCache) {
Expand Down Expand Up @@ -249,6 +250,11 @@ func getBuildOpts(cmd *cobra.Command) ([]leeway.BuildOption, *leeway.FilesystemC
} else if report != "" {
reporter = append(reporter, leeway.NewHTMLReporter(report))
}
if segmentkey, err := cmd.Flags().GetString("report-segment"); err != nil {
log.Fatal(err)
} else if segmentkey != "" {
reporter = append(reporter, leeway.NewSegmentReporter(segmentkey))
}

dontTest, err := cmd.Flags().GetBool("dont-test")
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ require (
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/opencontainers/selinux v1.10.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/seccomp/libseccomp-golang v0.10.0 // indirect
github.com/segmentio/analytics-go/v3 v3.2.1 // indirect
github.com/segmentio/backo-go v1.0.0 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
Expand Down Expand Up @@ -128,6 +130,10 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/segmentio/analytics-go/v3 v3.2.1 h1:G+f90zxtc1p9G+WigVyTR0xNfOghOGs/PYAlljLOyeg=
github.com/segmentio/analytics-go/v3 v3.2.1/go.mod h1:p8owAF8X+5o27jmvUognuXxdtqvSGtD0ZrfY2kcS9bE=
github.com/segmentio/backo-go v1.0.0 h1:kbOAtGJY2DqOR0jfRkYEorx/b18RgtepGtY3+Cpe6qA=
github.com/segmentio/backo-go v1.0.0/go.mod h1:kJ9mm9YmoWSkk+oQ+5Cj8DEoRCX2JT6As4kEtIIOp1M=
github.com/segmentio/textio v1.2.0 h1:Ug4IkV3kh72juJbG8azoSBlgebIbUUxVNrfFcKHfTSQ=
github.com/segmentio/textio v1.2.0/go.mod h1:+Rb7v0YVODP+tK5F7FD9TCkV7gOYx9IgLHWiqtvY8ag=
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
Expand Down
87 changes: 87 additions & 0 deletions pkg/leeway/reporter.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
package leeway

import (
"encoding/json"
"fmt"
"io"
"os"
"runtime"
"sort"
"strings"
"sync"
"text/tabwriter"
"text/template"
"time"

"github.com/google/uuid"
log "github.com/sirupsen/logrus"

"github.com/gookit/color"
segment "github.com/segmentio/analytics-go/v3"
"github.com/segmentio/textio"
)

Expand Down Expand Up @@ -477,3 +481,86 @@ func (*NoopReporter) PackageBuildLog(pkg *Package, isErr bool, buf []byte) {}
func (*NoopReporter) PackageBuildStarted(pkg *Package) {}

var _ Reporter = ((*NoopReporter)(nil))

func NewSegmentReporter(key string) *SegmentReporter {
id, err := uuid.NewRandom()
if err != nil {
panic(fmt.Errorf("cannot produce segment reporter anonymous ID: %w", err))
}
return &SegmentReporter{
AnonymousId: id.String(),
key: key,
times: make(map[string]time.Time),
}
}

type SegmentReporter struct {
NoopReporter

AnonymousId string
key string

client segment.Client
times map[string]time.Time
mu sync.Mutex
}

// BuildStarted implements Reporter
func (sr *SegmentReporter) BuildStarted(pkg *Package, status map[*Package]PackageBuildStatus) {
sr.mu.Lock()
defer sr.mu.Unlock()

sr.client = segment.New(sr.key)
}

func (sr *SegmentReporter) BuildFinished(pkg *Package, err error) {
sr.mu.Lock()
defer sr.mu.Unlock()

sr.client.Close()
sr.client = nil
}

func (sr *SegmentReporter) PackageBuildStarted(pkg *Package) {
sr.mu.Lock()
defer sr.mu.Unlock()

sr.times[pkg.FullName()] = time.Now()
}

func (sr *SegmentReporter) PackageBuildFinished(pkg *Package, perr error) {
props := segment.Properties{
"name": pkg.FullName(),
"repo": pkg.C.W.Git.Origin,
"dirtyWorkingCopy": pkg.C.W.Git.DirtyFiles(pkg.Sources),
"commit": pkg.C.W.Git.Commit,
"success": perr == nil,
}

sr.mu.Lock()
t0, ok := sr.times[pkg.FullName()]
sr.mu.Unlock()
if ok {
props["durationMS"] = time.Since(t0).Milliseconds()
}
evt := segment.Track{
AnonymousId: sr.AnonymousId,
Event: "package_build_finished",
Timestamp: time.Now(),
Context: &segment.Context{
App: segment.AppInfo{Name: "leeway", Version: Version},
OS: segment.OSInfo{Name: runtime.GOOS},
},
Properties: props,
}

err := sr.client.Enqueue(evt)
if err != nil {
log.WithError(err).Warn("cannot report build progress to segment")
}

if log.IsLevelEnabled(log.DebugLevel) {
fc, _ := json.Marshal(evt)
log.WithField("evt", string(fc)).Debug("reported segment event")
}
}

0 comments on commit c3e7bac

Please sign in to comment.