Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1650)

Side by Side Diff: appengine/cmd/milo/logdog/logDogBuild.go

Issue 2191693003: Milo: Add LogDog annotation stream support. (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: Rebarse Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package logdog 5 package logdog
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "strings"
10 "time" 9 "time"
11 10
12 "golang.org/x/net/context" 11 "golang.org/x/net/context"
13 12
14 "github.com/luci/luci-go/appengine/cmd/milo/resp" 13 "github.com/luci/luci-go/appengine/cmd/milo/resp"
15 "github.com/luci/luci-go/common/clock" 14 "github.com/luci/luci-go/common/clock"
16 "github.com/luci/luci-go/common/logging"
17 miloProto "github.com/luci/luci-go/common/proto/milo" 15 miloProto "github.com/luci/luci-go/common/proto/milo"
18 ) 16 )
19 17
18 // URLBuilder constructs URLs for various link types.
19 type URLBuilder interface {
20 // LinkURL returns the URL associated with the supplied Link.
21 //
22 // If no URL could be built for that Link, nil will be returned.
23 BuildLink(l *miloProto.Link) *resp.Link
24 }
25
20 // miloBuildStep converts a logdog/milo step to a BuildComponent struct. 26 // miloBuildStep converts a logdog/milo step to a BuildComponent struct.
21 // buildCompletedTime must be zero if build did not complete yet. 27 // buildCompletedTime must be zero if build did not complete yet.
22 func miloBuildStep(c context.Context, linkBase string, anno *miloProto.Step, bui ldCompletedTime time.Time) *resp.BuildComponent { 28 func miloBuildStep(ub URLBuilder, anno *miloProto.Step, buildCompletedTime, now time.Time) *resp.BuildComponent {
23 » linkBase = strings.TrimSuffix(linkBase, "/") 29
24 comp := &resp.BuildComponent{Label: anno.Name} 30 comp := &resp.BuildComponent{Label: anno.Name}
25 switch anno.Status { 31 switch anno.Status {
26 case miloProto.Status_RUNNING: 32 case miloProto.Status_RUNNING:
27 comp.Status = resp.Running 33 comp.Status = resp.Running
28 34
29 case miloProto.Status_SUCCESS: 35 case miloProto.Status_SUCCESS:
30 comp.Status = resp.Success 36 comp.Status = resp.Success
31 37
32 case miloProto.Status_FAILURE: 38 case miloProto.Status_FAILURE:
33 » » if anno.GetFailureDetails() != nil { 39 » » if fd := anno.GetFailureDetails(); fd != nil {
34 » » » switch anno.GetFailureDetails().Type { 40 » » » switch fd.Type {
35 case miloProto.FailureDetails_EXCEPTION, miloProto.Failu reDetails_INFRA: 41 case miloProto.FailureDetails_EXCEPTION, miloProto.Failu reDetails_INFRA:
36 comp.Status = resp.InfraFailure 42 comp.Status = resp.InfraFailure
37 43
38 case miloProto.FailureDetails_DM_DEPENDENCY_FAILED: 44 case miloProto.FailureDetails_DM_DEPENDENCY_FAILED:
39 comp.Status = resp.DependencyFailure 45 comp.Status = resp.DependencyFailure
40 46
41 default: 47 default:
42 comp.Status = resp.Failure 48 comp.Status = resp.Failure
43 } 49 }
50
51 if fd.Text != "" {
52 comp.Text = append(comp.Text, fd.Text)
53 }
44 } else { 54 } else {
45 comp.Status = resp.Failure 55 comp.Status = resp.Failure
46 } 56 }
47 57
58 case miloProto.Status_PENDING:
59 comp.Status = resp.NotRun
60
48 // Missing the case of waiting on unfinished dependency... 61 // Missing the case of waiting on unfinished dependency...
49 default: 62 default:
50 comp.Status = resp.NotRun 63 comp.Status = resp.NotRun
51 } 64 }
52 65
53 » if !buildCompletedTime.IsZero() && !comp.Status.Terminal() { 66 » if !(buildCompletedTime.IsZero() || comp.Status.Terminal()) {
54 » » // we cannot have unfinished steps in finished builds. 67 » » // The build has completed, but this step has not. Mark it as an
68 » » // infrastructure failure.
55 comp.Status = resp.InfraFailure 69 comp.Status = resp.InfraFailure
56 } 70 }
57 71
72 // Main link is a link to the stdout.
73 var stdoutLink *miloProto.Link
74 if anno.StdoutStream != nil {
75 stdoutLink = &miloProto.Link{
76 Label: "stdout",
77 Value: &miloProto.Link_LogdogStream{
78 LogdogStream: anno.StdoutStream,
79 },
80 }
81 }
82
83 if anno.Link != nil {
84 comp.MainLink = ub.BuildLink(anno.Link)
85
86 // If we also have a STDOUT stream, add it to our OtherLinks.
87 if stdoutLink != nil {
88 anno.OtherLinks = append([]*miloProto.Link{stdoutLink}, anno.OtherLinks...)
89 }
90 } else if stdoutLink != nil {
91 comp.MainLink = ub.BuildLink(stdoutLink)
92 }
93
58 // Sub link is for one link per log that isn't stdout. 94 // Sub link is for one link per log that isn't stdout.
59 for _, link := range anno.GetOtherLinks() { 95 for _, link := range anno.GetOtherLinks() {
60 » » lds := link.GetLogdogStream() 96 » » if l := ub.BuildLink(link); l != nil {
61 » » if lds == nil { 97 » » » comp.SubLink = append(comp.SubLink, l)
62 » » » logging.Warningf(c, "Warning: %v of %v has an empty logd og stream.", link, anno)
63 » » » continue // DNE???
64 » » }
65 » » newLink := &resp.Link{
66 » » » Label: lds.Name,
67 » » » URL: linkBase + "/" + lds.Name,
68 » » }
69 » » comp.SubLink = append(comp.SubLink, newLink)
70 » }
71
72 » // Main link is a link to the stdout.
73 » if anno.StdoutStream != nil {
74 » » comp.MainLink = &resp.Link{
75 » » » Label: "stdout",
76 » » » URL: linkBase + "/" + anno.StdoutStream.Name,
77 } 98 }
78 } 99 }
79 100
80 // This should always be a step. 101 // This should always be a step.
81 comp.Type = resp.Step 102 comp.Type = resp.Step
82 103
83 // This should always be 0 104 // This should always be 0
84 comp.LevelsDeep = 0 105 comp.LevelsDeep = 0
85 106
86 // Timestamps 107 // Timestamps
87 comp.Started = anno.Started.Time() 108 comp.Started = anno.Started.Time()
88 comp.Finished = anno.Ended.Time() 109 comp.Finished = anno.Ended.Time()
89 110
90 var till time.Time 111 var till time.Time
91 switch { 112 switch {
92 case comp.Status == resp.Running:
93 till = clock.Now(c)
94 case !comp.Finished.IsZero(): 113 case !comp.Finished.IsZero():
95 till = comp.Finished 114 till = comp.Finished
96 » default: 115 » case comp.Status == resp.Running:
116 » » till = now
117 » case !buildCompletedTime.IsZero():
97 till = buildCompletedTime 118 till = buildCompletedTime
98 } 119 }
99 » if !comp.Started.IsZero() && !till.IsZero() { 120 » if !comp.Started.IsZero() && till.After(comp.Started) {
100 comp.Duration = till.Sub(comp.Started) 121 comp.Duration = till.Sub(comp.Started)
101 } 122 }
102 123
103 // This should be the exact same thing. 124 // This should be the exact same thing.
104 » comp.Text = anno.Text 125 » comp.Text = append(comp.Text, anno.Text...)
105 126
106 return comp 127 return comp
107 } 128 }
108 129
109 // AddLogDogToBuild takes a set of logdog streams and populate a milo build. 130 // AddLogDogToBuild takes a set of logdog streams and populate a milo build.
110 // build.Summary.Finished must be set. 131 // build.Summary.Finished must be set.
111 func AddLogDogToBuild(c context.Context, linkBase string, s *Streams, build *res p.MiloBuild) { 132 func AddLogDogToBuild(c context.Context, ub URLBuilder, s *Streams, build *resp. MiloBuild) {
112 if s.MainStream == nil { 133 if s.MainStream == nil {
113 panic("missing main stream") 134 panic("missing main stream")
114 } 135 }
115 // Now Fetch the main annotation of the build. 136 // Now Fetch the main annotation of the build.
116 » mainAnno := s.MainStream.Data 137 » var (
138 » » mainAnno = s.MainStream.Data
139 » » now = clock.Now(c)
140 » )
117 141
118 // Now fill in each of the step components. 142 // Now fill in each of the step components.
119 // TODO(hinoka): This is totes cachable. 143 // TODO(hinoka): This is totes cachable.
144 buildCompletedTime := mainAnno.Ended.Time()
145 build.Summary = *(miloBuildStep(ub, mainAnno, buildCompletedTime, now))
120 for _, substepContainer := range mainAnno.Substep { 146 for _, substepContainer := range mainAnno.Substep {
121 anno := substepContainer.GetStep() 147 anno := substepContainer.GetStep()
122 if anno == nil { 148 if anno == nil {
123 // TODO: We ignore non-embedded substeps for now. 149 // TODO: We ignore non-embedded substeps for now.
124 continue 150 continue
125 } 151 }
126 152
127 » » bs := miloBuildStep(c, linkBase, anno, build.Summary.Finished) 153 » » bs := miloBuildStep(ub, anno, buildCompletedTime, now)
128 » » if bs.Status != resp.Success && bs.Status != resp.NotRun { 154 » » if bs.Status != resp.Success {
129 build.Summary.Text = append( 155 build.Summary.Text = append(
130 build.Summary.Text, fmt.Sprintf("%s %s", bs.Stat us, bs.Label)) 156 build.Summary.Text, fmt.Sprintf("%s %s", bs.Stat us, bs.Label))
131 } 157 }
132 build.Components = append(build.Components, bs) 158 build.Components = append(build.Components, bs)
133 propGroup := &resp.PropertyGroup{GroupName: bs.Label} 159 propGroup := &resp.PropertyGroup{GroupName: bs.Label}
134 for _, prop := range anno.Property { 160 for _, prop := range anno.Property {
135 propGroup.Property = append(propGroup.Property, &resp.Pr operty{ 161 propGroup.Property = append(propGroup.Property, &resp.Pr operty{
136 Key: prop.Name, 162 Key: prop.Name,
137 Value: prop.Value, 163 Value: prop.Value,
138 }) 164 })
139 } 165 }
140 build.PropertyGroup = append(build.PropertyGroup, propGroup) 166 build.PropertyGroup = append(build.PropertyGroup, propGroup)
141 } 167 }
142 168
143 // Take care of properties 169 // Take care of properties
144 propGroup := &resp.PropertyGroup{GroupName: "Main"} 170 propGroup := &resp.PropertyGroup{GroupName: "Main"}
145 for _, prop := range mainAnno.Property { 171 for _, prop := range mainAnno.Property {
146 propGroup.Property = append(propGroup.Property, &resp.Property{ 172 propGroup.Property = append(propGroup.Property, &resp.Property{
147 Key: prop.Name, 173 Key: prop.Name,
148 Value: prop.Value, 174 Value: prop.Value,
149 }) 175 })
150 } 176 }
151 build.PropertyGroup = append(build.PropertyGroup, propGroup) 177 build.PropertyGroup = append(build.PropertyGroup, propGroup)
152 178
153 return 179 return
154 } 180 }
OLDNEW
« no previous file with comments | « appengine/cmd/milo/logdog/internal/stream.pb.go ('k') | appengine/cmd/milo/logdog/logDogStream.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698