moira
77 строк · 2.1 Кб
1package controller
2
3import (
4"sort"
5"time"
6
7"go.avito.ru/DO/moira"
8"go.avito.ru/DO/moira/api"
9"go.avito.ru/DO/moira/api/dto"
10)
11
12func GetMetricStats(database moira.Database, intervalLength int64, onlyErrors bool, filterTags []string) (*dto.MetricStats, *api.ErrorResponse) {
13var (
14intervalEnd = time.Now().Unix()
15intervalStart = intervalEnd - intervalLength
16)
17allEvents, err := database.GetAllNotificationEvents(intervalStart, intervalEnd)
18if err != nil {
19return nil, api.ErrorInternalServer(err)
20}
21
22triggerIDList, err := database.GetTriggerCheckIDs(filterTags, onlyErrors)
23if err != nil {
24return nil, api.ErrorInternalServer(err)
25}
26// get trigger data
27triggerDataList, err := database.GetTriggers(triggerIDList)
28if err != nil {
29return nil, api.ErrorInternalServer(err)
30}
31// make a Trigger ID-to-data map
32triggerData := make(map[string]*moira.Trigger, len(triggerDataList))
33for _, trigger := range triggerDataList {
34triggerData[trigger.ID] = trigger
35}
36
37type metricKey struct {
38Metric string
39TriggerID string
40}
41errorCounts := make(map[metricKey]int64)
42currentStates := make(map[metricKey]string)
43for _, event := range allEvents {
44if event.IsTriggerEvent {
45continue
46}
47if _, found := triggerData[event.TriggerID]; found {
48// this trigger does have the tags we want
49key := metricKey{Metric: event.Metric, TriggerID: event.TriggerID}
50if event.OldState == moira.OK && event.State != moira.OK {
51// this is a flap, add it to the stats
52errorCounts[key] += 1
53}
54currentStates[key] = event.State
55}
56}
57
58result := dto.MetricStats{
59List: make([]*dto.MetricStatModel, 0, len(errorCounts)),
60}
61for key, errorCount := range errorCounts {
62if onlyErrors && currentStates[key] == moira.OK {
63continue
64}
65stat := dto.MetricStatModel{
66Metric: key.Metric,
67Trigger: dto.CreateTriggerModel(triggerData[key.TriggerID]),
68ErrorCount: errorCount,
69CurrentState: currentStates[key],
70}
71result.List = append(result.List, &stat)
72}
73sort.SliceStable(result.List, func(i, j int) bool {
74return result.List[i].ErrorCount > result.List[j].ErrorCount
75})
76return &result, nil
77}
78