Esempio n. 1
0
func getAndFilterAnnotations(e *State, start, end time.Time, filter string) (annotate.Annotations, error) {
	annotations, err := e.AnnotateContext.GetAnnotations(&start, &end, "", "", "", "", "", "", "")
	if err != nil {
		return nil, err
	}
	var t *boolq.Tree
	if filter != "" {
		var err error
		t, err = boolq.Parse(filter)
		if err != nil {
			return nil, fmt.Errorf("failed to parse annotation filter: %v", err)
		}
	}
	filteredAnnotations := annotate.Annotations{}
	for _, a := range annotations {
		if filter == "" {
			filteredAnnotations = append(filteredAnnotations, a)
			continue
		}
		match, err := boolq.AskParsedExpr(t, a)
		if err != nil {
			return nil, err
		}
		if match {
			filteredAnnotations = append(filteredAnnotations, a)
		}
	}
	sort.Sort(sort.Reverse(annotate.AnnotationsByStartID(filteredAnnotations)))
	return filteredAnnotations, nil
}
Esempio n. 2
0
func ListOpenIncidents(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) (interface{}, error) {
	// TODO: Retune this when we no longer store email bodies with incidents
	list, err := schedule.DataAccess.State().GetAllOpenIncidents()
	if err != nil {
		return nil, err
	}
	suppressor := schedule.Silenced()
	if suppressor == nil {
		return nil, fmt.Errorf("failed to get silences")
	}
	summaries := []*sched.IncidentSummaryView{}
	filterText := r.FormValue("filter")
	var parsedExpr *boolq.Tree
	parsedExpr, err = boolq.Parse(filterText)
	if err != nil {
		return nil, fmt.Errorf("bad filter: %v", err)
	}
	for _, iState := range list {
		is, err := sched.MakeIncidentSummary(schedule.RuleConf, suppressor, iState)
		if err != nil {
			return nil, err
		}
		match, err := boolq.AskParsedExpr(parsedExpr, is)
		if err != nil {
			return nil, err
		}
		if match {
			summaries = append(summaries, is)
		}
	}
	return summaries, nil
}
Esempio n. 3
0
func (s *Schedule) MarshalGroups(T miniprofiler.Timer, filter string) (*StateGroups, error) {
	var silenced SilenceTester
	T.Step("Silenced", func(miniprofiler.Timer) {
		silenced = s.Silenced()
	})
	var groups map[StateTuple]States
	var err error
	status := make(States)
	t := StateGroups{
		TimeAndDate: s.SystemConf.GetTimeAndDate(),
	}
	t.FailingAlerts, t.UnclosedErrors = s.getErrorCounts()
	T.Step("Setup", func(miniprofiler.Timer) {
		status2, err2 := s.GetOpenStates()
		if err2 != nil {
			err = err2
			return
		}
		var parsedExpr *boolq.Tree
		parsedExpr, err2 = boolq.Parse(filter)
		if err2 != nil {
			err = err2
			return
		}
		for k, v := range status2 {
			a := s.RuleConf.GetAlert(k.Name())
			if a == nil {
				slog.Errorf("unknown alert %s. Force closing.", k.Name())
				if err2 = s.ActionByAlertKey("bosun", "closing because alert doesn't exist.", models.ActionForceClose, k); err2 != nil {
					slog.Error(err2)
				}
				continue
			}
			is, err2 := MakeIncidentSummary(s.RuleConf, silenced, v)
			if err2 != nil {
				err = err2
				return
			}
			match := false
			match, err2 = boolq.AskParsedExpr(parsedExpr, is)
			if err2 != nil {
				err = err2
				return
			}
			if match {
				status[k] = v
			}
		}
	})
	if err != nil {
		return nil, err
	}
	T.Step("GroupStates", func(T miniprofiler.Timer) {
		groups = status.GroupStates(silenced)
	})
	T.Step("groups", func(T miniprofiler.Timer) {
		for tuple, states := range groups {
			var grouped []*StateGroup
			switch tuple.Status {
			case models.StWarning, models.StCritical, models.StUnknown:
				var sets map[string]models.AlertKeys
				T.Step(fmt.Sprintf("GroupSets (%d): %v", len(states), tuple), func(T miniprofiler.Timer) {
					sets = states.GroupSets(s.SystemConf.GetMinGroupSize())
				})
				for name, group := range sets {
					g := StateGroup{
						Active:        tuple.Active,
						Status:        tuple.Status,
						CurrentStatus: tuple.CurrentStatus,
						Silenced:      tuple.Silenced,
						Subject:       fmt.Sprintf("%s - %s", tuple.Status, name),
					}
					for _, ak := range group {
						st := status[ak]
						st.Body = ""
						st.EmailBody = nil
						st.Attachments = nil
						g.Children = append(g.Children, &StateGroup{
							Active:   tuple.Active,
							Status:   tuple.Status,
							Silenced: tuple.Silenced,
							AlertKey: ak,
							Alert:    ak.Name(),
							Subject:  string(st.Subject),
							Ago:      marshalTime(st.Last().Time),
							State:    st,
							IsError:  !s.AlertSuccessful(ak.Name()),
						})
					}
					if len(g.Children) == 1 && g.Children[0].Subject != "" {
						g.Subject = g.Children[0].Subject
					}
					grouped = append(grouped, &g)
				}
			default:
				continue
			}
			if tuple.NeedAck {
				t.Groups.NeedAck = append(t.Groups.NeedAck, grouped...)
			} else {
				t.Groups.Acknowledged = append(t.Groups.Acknowledged, grouped...)
			}
		}
	})
	T.Step("sort", func(T miniprofiler.Timer) {
		gsort := func(grp []*StateGroup) func(i, j int) bool {
			return func(i, j int) bool {
				a := grp[i]
				b := grp[j]
				if a.Active && !b.Active {
					return true
				} else if !a.Active && b.Active {
					return false
				}
				if a.Status != b.Status {
					return a.Status > b.Status
				}
				if a.AlertKey != b.AlertKey {
					return a.AlertKey < b.AlertKey
				}
				return a.Subject < b.Subject
			}
		}
		slice.Sort(t.Groups.NeedAck, gsort(t.Groups.NeedAck))
		slice.Sort(t.Groups.Acknowledged, gsort(t.Groups.Acknowledged))
	})
	return &t, nil
}