Chromium Code Reviews| Index: go/src/infra/monitoring/dispatcher/dispatcher.go |
| diff --git a/go/src/infra/monitoring/dispatcher/dispatcher.go b/go/src/infra/monitoring/dispatcher/dispatcher.go |
| index d81ccf058ca5f0bd006c7347a13f1d65e6a8ba5a..3c9edc8be549cb3f4df2c111e51a0638879839d7 100644 |
| --- a/go/src/infra/monitoring/dispatcher/dispatcher.go |
| +++ b/go/src/infra/monitoring/dispatcher/dispatcher.go |
| @@ -16,6 +16,7 @@ import ( |
| "io/ioutil" |
| "net/http" |
| "os" |
| + "sort" |
| "strings" |
| "time" |
| @@ -55,10 +56,7 @@ var ( |
| duration, cycle time.Duration |
| // gk is the gatekeeper config. |
| - gk = &struct { |
| - // Weird. Are there ever multiple configs per master key? |
| - Masters map[string][]messages.MasterConfig `json:"masters"` |
| - }{} |
| + gk = &messages.GatekeeperConfig{} |
| // gkt is the gatekeeper trees config. |
| gkt = map[string]messages.TreeMasterConfig{} |
| filteredFailures = uint64(0) |
| @@ -128,6 +126,14 @@ func fetchBuildExtracts(c client.Reader, masterNames []string) map[string]*messa |
| return bes |
| } |
| +type bySeverity []messages.Alert |
| + |
| +func (a bySeverity) Len() int { return len(a) } |
| +func (a bySeverity) Swap(i, j int) { a[i], a[j] = a[j], a[i] } |
| +func (a bySeverity) Less(i, j int) bool { |
| + return a[i].Severity < a[j].Severity |
| +} |
| + |
| func mainLoop(ctx context.Context, a *analyzer.Analyzer, trees map[string]bool) error { |
| done := make(chan interface{}) |
| errs := make(chan error) |
| @@ -153,6 +159,8 @@ func mainLoop(ctx context.Context, a *analyzer.Analyzer, trees map[string]bool) |
| alerts.Alerts = append(alerts.Alerts, analyzeBuildExtract(a, masterName, be)...) |
| } |
| + sort.Sort(bySeverity(alerts.Alerts)) |
| + |
| // Make sure we have summaries for each revision implicated in a builder failure. |
| for _, alert := range alerts.Alerts { |
| if bf, ok := alert.Extension.(messages.BuildFailure); ok { |
| @@ -298,16 +306,29 @@ func main() { |
| diff := time.Now().Sub(start) |
| return t.Add(diff) |
| } |
| - } |
| + } else if *replay != "" { |
| + f, err := os.Open(*replay) |
| + defer f.Close() |
| + 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
|
| + log.Errorf("Couldn't open replay dir: %s", err) |
| + os.Exit(1) |
| + } |
| + stat, err := f.Stat() |
| + if err != nil { |
| + log.Errorf("Couldn't stat replay dir: %s", err) |
| + os.Exit(1) |
| + } |
| + start := time.Now() |
| + t := stat.ModTime() |
| - for masterURL, masterCfgs := range gk.Masters { |
| - if len(masterCfgs) != 1 { |
| - log.Errorf("Multiple configs for master: %s", masterURL) |
| + a.Now = func() time.Time { |
| + diff := time.Now().Sub(start) |
| + return t.Add(diff) |
| } |
| - masterName := masterFromURL(masterURL) |
| - a.MasterCfgs[masterName] = masterCfgs[0] |
| } |
| + 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.
|
| + |
| a.MasterOnly = *masterOnly |
| a.BuilderOnly = *builderOnly |
| a.BuildOnly = *buildOnly |