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

Side by Side Diff: go/src/infra/monitoring/dispatcher/dispatcher.go

Issue 1874053002: [alerts-dispatcher] update to build again :) also fixes a concurrent map access (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: make tests compile. still don't pass though Created 4 years, 8 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Dispatcher usage: 5 // Dispatcher usage:
6 // go run infra/monitoring/dispatcher 6 // go run infra/monitoring/dispatcher
7 // Expects gatekeeper.json to be in the current directory. 7 // Expects gatekeeper.json to be in the current directory.
8 8
9 package main 9 package main
10 10
11 import ( 11 import (
12 "encoding/json" 12 "encoding/json"
13 "expvar" 13 "expvar"
14 "flag" 14 "flag"
15 "fmt" 15 "fmt"
16 "io/ioutil" 16 "io/ioutil"
17 "net/http" 17 "net/http"
18 "os" 18 "os"
19 "sort"
19 "strings" 20 "strings"
20 "time" 21 "time"
21 22
22 "github.com/luci/luci-go/common/auth" 23 "github.com/luci/luci-go/common/auth"
23 "github.com/luci/luci-go/common/clock" 24 "github.com/luci/luci-go/common/clock"
24 "github.com/luci/luci-go/common/logging" 25 "github.com/luci/luci-go/common/logging"
25 "github.com/luci/luci-go/common/logging/gologger" 26 "github.com/luci/luci-go/common/logging/gologger"
26 27
27 "golang.org/x/net/context" 28 "golang.org/x/net/context"
28 29
(...skipping 19 matching lines...) Expand all
48 cycleStr = flag.String("cycle", "1s", "Cycle time for loop") 49 cycleStr = flag.String("cycle", "1s", "Cycle time for loop")
49 snapshot = flag.String("record-snapshot", "", "Save a snapsho t of infra responses to this path, which will be created if it does not already exist.") 50 snapshot = flag.String("record-snapshot", "", "Save a snapsho t of infra responses to this path, which will be created if it does not already exist.")
50 replay = flag.String("replay-snapshot", "", "Replay a snaps hot of infra responses from this path, which should have been created previously by running with --record-snapshot.") 51 replay = flag.String("replay-snapshot", "", "Replay a snaps hot of infra responses from this path, which should have been created previously by running with --record-snapshot.")
51 replayTime = flag.String("replay-time", "", "Specify a simulate d starting time for the replay in RFC3339 format, used with --replay-snapshot.") 52 replayTime = flag.String("replay-time", "", "Specify a simulate d starting time for the replay in RFC3339 format, used with --replay-snapshot.")
52 serviceAccountJSON = flag.String("service-account", "", "Service accoun t JSON file.") 53 serviceAccountJSON = flag.String("service-account", "", "Service accoun t JSON file.")
53 54
54 log = gologger.Get() 55 log = gologger.Get()
55 duration, cycle time.Duration 56 duration, cycle time.Duration
56 57
57 // gk is the gatekeeper config. 58 // gk is the gatekeeper config.
58 » gk = &struct { 59 » gk = &messages.GatekeeperConfig{}
59 » » // Weird. Are there ever multiple configs per master key?
60 » » Masters map[string][]messages.MasterConfig `json:"masters"`
61 » }{}
62 // gkt is the gatekeeper trees config. 60 // gkt is the gatekeeper trees config.
63 gkt = map[string]messages.TreeMasterConfig{} 61 gkt = map[string]messages.TreeMasterConfig{}
64 filteredFailures = uint64(0) 62 filteredFailures = uint64(0)
65 expvars = expvar.NewMap("dispatcher") 63 expvars = expvar.NewMap("dispatcher")
66 ) 64 )
67 65
68 func init() { 66 func init() {
69 flag.Usage = func() { 67 flag.Usage = func() {
70 fmt.Printf("By default runs a single check, saves any alerts to ./alerts.json and exits.") 68 fmt.Printf("By default runs a single check, saves any alerts to ./alerts.json and exits.")
71 flag.PrintDefaults() 69 flag.PrintDefaults()
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 119
122 for range masterNames { 120 for range masterNames {
123 r := <-res 121 r := <-res
124 if r.be != nil { 122 if r.be != nil {
125 bes[r.name] = r.be 123 bes[r.name] = r.be
126 } 124 }
127 } 125 }
128 return bes 126 return bes
129 } 127 }
130 128
129 type bySeverity []messages.Alert
130
131 func (a bySeverity) Len() int { return len(a) }
132 func (a bySeverity) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
133 func (a bySeverity) Less(i, j int) bool {
134 return a[i].Severity < a[j].Severity
135 }
136
131 func mainLoop(ctx context.Context, a *analyzer.Analyzer, trees map[string]bool) error { 137 func mainLoop(ctx context.Context, a *analyzer.Analyzer, trees map[string]bool) error {
132 done := make(chan interface{}) 138 done := make(chan interface{})
133 errs := make(chan error) 139 errs := make(chan error)
134 for treeName := range trees { 140 for treeName := range trees {
135 go func(tree string) { 141 go func(tree string) {
136 expvars.Add(fmt.Sprintf("Tree-%s", tree), 1) 142 expvars.Add(fmt.Sprintf("Tree-%s", tree), 1)
137 defer expvars.Add(fmt.Sprintf("Tree-%s", tree), -1) 143 defer expvars.Add(fmt.Sprintf("Tree-%s", tree), -1)
138 log.Infof("Checking tree: %s", tree) 144 log.Infof("Checking tree: %s", tree)
139 masterNames := []string{} 145 masterNames := []string{}
140 t := gkt[tree] 146 t := gkt[tree]
141 for _, url := range t.Masters { 147 for _, url := range t.Masters {
142 masterNames = append(masterNames, masterFromURL( url)) 148 masterNames = append(masterNames, masterFromURL( url))
143 } 149 }
144 150
145 // TODO(seanmccullough): Plumb ctx through the rest of t hese calls. 151 // TODO(seanmccullough): Plumb ctx through the rest of t hese calls.
146 bes := fetchBuildExtracts(a.Reader, masterNames) 152 bes := fetchBuildExtracts(a.Reader, masterNames)
147 log.Infof("Build Extracts read: %d", len(bes)) 153 log.Infof("Build Extracts read: %d", len(bes))
148 154
149 alerts := &messages.Alerts{ 155 alerts := &messages.Alerts{
150 RevisionSummaries: map[string]messages.RevisionS ummary{}, 156 RevisionSummaries: map[string]messages.RevisionS ummary{},
151 } 157 }
152 for masterName, be := range bes { 158 for masterName, be := range bes {
153 alerts.Alerts = append(alerts.Alerts, analyzeBui ldExtract(a, masterName, be)...) 159 alerts.Alerts = append(alerts.Alerts, analyzeBui ldExtract(a, masterName, be)...)
154 } 160 }
155 161
162 sort.Sort(bySeverity(alerts.Alerts))
163
156 // Make sure we have summaries for each revision implica ted in a builder failure. 164 // Make sure we have summaries for each revision implica ted in a builder failure.
157 for _, alert := range alerts.Alerts { 165 for _, alert := range alerts.Alerts {
158 if bf, ok := alert.Extension.(messages.BuildFail ure); ok { 166 if bf, ok := alert.Extension.(messages.BuildFail ure); ok {
159 for _, r := range bf.RegressionRanges { 167 for _, r := range bf.RegressionRanges {
160 revs, err := a.GetRevisionSummar ies(r.Revisions) 168 revs, err := a.GetRevisionSummar ies(r.Revisions)
161 if err != nil { 169 if err != nil {
162 log.Errorf("Couldn't get revision summaries: %v", err) 170 log.Errorf("Couldn't get revision summaries: %v", err)
163 continue 171 continue
164 } 172 }
165 for _, rev := range revs { 173 for _, rev := range revs {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 268 }
261 269
262 err = readJSONFile(*gatekeeperJSON, &gk) 270 err = readJSONFile(*gatekeeperJSON, &gk)
263 if err != nil { 271 if err != nil {
264 log.Errorf("Error reading gatekeeper json: %v", err) 272 log.Errorf("Error reading gatekeeper json: %v", err)
265 os.Exit(1) 273 os.Exit(1)
266 } 274 }
267 275
268 err = readJSONFile(*gatekeeperTreesJSON, &gkt) 276 err = readJSONFile(*gatekeeperTreesJSON, &gkt)
269 if err != nil { 277 if err != nil {
270 log.Errorf("Error reading gatekeeper json: %v", err) 278 log.Errorf("Error reading gatekeeper json: %v", err)
martiniss 2016/04/11 21:33:34 Maybe update this error to say "Error reading gate
seanmccullough 2016/04/11 23:11:08 Done.
271 os.Exit(1) 279 os.Exit(1)
272 } 280 }
273 281
274 if *snapshot != "" && *replay != "" { 282 if *snapshot != "" && *replay != "" {
275 log.Errorf("Cannot use snapshot and replay flags at the same tim e.") 283 log.Errorf("Cannot use snapshot and replay flags at the same tim e.")
276 os.Exit(1) 284 os.Exit(1)
277 } 285 }
278 286
279 r := client.NewReader(transport) 287 r := client.NewReader(transport)
280 288
(...skipping 10 matching lines...) Expand all
291 t, err := time.Parse(time.RFC3339, *replayTime) 299 t, err := time.Parse(time.RFC3339, *replayTime)
292 if err != nil { 300 if err != nil {
293 log.Errorf("Couldn't parse replay-time: %s", err) 301 log.Errorf("Couldn't parse replay-time: %s", err)
294 os.Exit(1) 302 os.Exit(1)
295 } 303 }
296 start := time.Now() 304 start := time.Now()
297 a.Now = func() time.Time { 305 a.Now = func() time.Time {
298 diff := time.Now().Sub(start) 306 diff := time.Now().Sub(start)
299 return t.Add(diff) 307 return t.Add(diff)
300 } 308 }
309 } else if *replay != "" {
310 f, err := os.Open(*replay)
311 defer f.Close()
312 if err != nil {
martiniss 2016/04/11 21:33:34 I think you need to handle the error before you cl
seanmccullough 2016/04/11 23:11:08 defer runs its argument right before the return of
313 log.Errorf("Couldn't open replay dir: %s", err)
314 os.Exit(1)
315 }
316 stat, err := f.Stat()
317 if err != nil {
318 log.Errorf("Couldn't stat replay dir: %s", err)
319 os.Exit(1)
320 }
321 start := time.Now()
322 t := stat.ModTime()
323
324 a.Now = func() time.Time {
325 diff := time.Now().Sub(start)
326 return t.Add(diff)
327 }
301 } 328 }
302 329
303 » for masterURL, masterCfgs := range gk.Masters { 330 » a.Gatekeeper = analyzer.NewGatekeeperRules(*gk)
martiniss 2016/04/11 21:33:34 I can't seem to find this function... where is it?
seanmccullough 2016/04/11 23:11:08 Forgot to add a file. Added.
304 » » if len(masterCfgs) != 1 {
305 » » » log.Errorf("Multiple configs for master: %s", masterURL)
306 » » }
307 » » masterName := masterFromURL(masterURL)
308 » » a.MasterCfgs[masterName] = masterCfgs[0]
309 » }
310 331
311 a.MasterOnly = *masterOnly 332 a.MasterOnly = *masterOnly
312 a.BuilderOnly = *builderOnly 333 a.BuilderOnly = *builderOnly
313 a.BuildOnly = *buildOnly 334 a.BuildOnly = *buildOnly
314 335
315 trees := map[string]bool{} 336 trees := map[string]bool{}
316 if *treesOnly != "" { 337 if *treesOnly != "" {
317 for _, treeOnly := range strings.Split(*treesOnly, ",") { 338 for _, treeOnly := range strings.Split(*treesOnly, ",") {
318 trees[treeOnly] = true 339 trees[treeOnly] = true
319 } 340 }
(...skipping 20 matching lines...) Expand all
340 logging.Set(ctx, log) 361 logging.Set(ctx, log)
341 defer cancel() 362 defer cancel()
342 363
343 loopResults := looper.Run(ctx, f, cycle, *maxErrs, clock.GetSystemClock( )) 364 loopResults := looper.Run(ctx, f, cycle, *maxErrs, clock.GetSystemClock( ))
344 365
345 if !loopResults.Success { 366 if !loopResults.Success {
346 log.Errorf("Failed to run loop, %v errors", loopResults.Errs) 367 log.Errorf("Failed to run loop, %v errors", loopResults.Errs)
347 os.Exit(1) 368 os.Exit(1)
348 } 369 }
349 } 370 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698