这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified cmd/bosun/docker/docker.sh
100644 → 100755
Empty file.
93 changes: 57 additions & 36 deletions cmd/bosun/sched/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func init() {
metadata.AddMetricMeta(
"bosun.alerts.active_status", metadata.Gauge, metadata.Alert,
"The number of open alerts by active status.")
collect.AggregateMeta("bosun.template.render", metadata.MilliSecond, "The amount of time it takes to render the specified alert template.")
}

func NewStatus(ak expr.AlertKey) *State {
Expand Down Expand Up @@ -128,44 +129,11 @@ func (s *Schedule) RunHistory(r *RunHistory) {
event.IncidentId = s.createIncident(ak, event.Time).Id
}
state.Append(event)

a := s.Conf.Alerts[ak.Name()]
wasOpen := state.Open
if event.Status > StNormal {
state.Subject = ""
state.Body = ""
state.EmailBody = nil
state.EmailSubject = nil
state.Attachments = nil
if event.Status != StUnknown {
subject, serr := s.ExecuteSubject(r, a, state, false)
if serr != nil {
log.Printf("%s: %v", state.AlertKey(), serr)
}
body, _, berr := s.ExecuteBody(r, a, state, false)
if berr != nil {
log.Printf("%s: %v", state.AlertKey(), berr)
}
emailbody, attachments, merr := s.ExecuteBody(r, a, state, true)
if merr != nil {
log.Printf("%s: %v", state.AlertKey(), merr)
}
emailsubject, eserr := s.ExecuteSubject(r, a, state, true)
if serr != nil || berr != nil || merr != nil || eserr != nil {
var err error
subject, body, err = s.ExecuteBadTemplate(serr, berr, r, a, state)
if err != nil {
subject = []byte(fmt.Sprintf("unable to create template error notification: %v", err))
}
emailbody = body
attachments = nil
}
state.Subject = string(subject)
state.Body = string(body)
state.EmailBody = emailbody
state.EmailSubject = emailsubject
state.Attachments = attachments
}

s.executeTemplates(state, event, a, r)
state.Open = true
if a.Log {
state.Open = false
Expand Down Expand Up @@ -250,6 +218,60 @@ func (s *Schedule) RunHistory(r *RunHistory) {
s.CollectStates()
}

func (s *Schedule) executeTemplates(state *State, event *Event, a *conf.Alert, r *RunHistory) {
state.Subject = ""
state.Body = ""
state.EmailBody = nil
state.EmailSubject = nil
state.Attachments = nil
if event.Status != StUnknown {
metric := "template.render"
//Render subject
endTiming := collect.StartTimer(metric, opentsdb.TagSet{"alert": a.Name, "type": "subject"})
subject, serr := s.ExecuteSubject(r, a, state, false)
if serr != nil {
log.Printf("%s: %v", state.AlertKey(), serr)
}
endTiming()
//Render body
endTiming = collect.StartTimer(metric, opentsdb.TagSet{"alert": a.Name, "type": "body"})
body, _, berr := s.ExecuteBody(r, a, state, false)
if berr != nil {
log.Printf("%s: %v", state.AlertKey(), berr)
}
endTiming()
//Render email body
endTiming = collect.StartTimer(metric, opentsdb.TagSet{"alert": a.Name, "type": "emailbody"})
emailbody, attachments, merr := s.ExecuteBody(r, a, state, true)
if merr != nil {
log.Printf("%s: %v", state.AlertKey(), merr)
}
endTiming()
//Render email subject
endTiming = collect.StartTimer(metric, opentsdb.TagSet{"alert": a.Name, "type": "emailsubject"})
emailsubject, eserr := s.ExecuteSubject(r, a, state, true)
endTiming()
if serr != nil || berr != nil || merr != nil || eserr != nil {
var err error

endTiming = collect.StartTimer(metric, opentsdb.TagSet{"alert": a.Name, "type": "bad"})
subject, body, err = s.ExecuteBadTemplate(serr, berr, r, a, state)
endTiming()

if err != nil {
subject = []byte(fmt.Sprintf("unable to create template error notification: %v", err))
}
emailbody = body
attachments = nil
}
state.Subject = string(subject)
state.Body = string(body)
state.EmailBody = emailbody
state.EmailSubject = emailsubject
state.Attachments = attachments
}
}

// CollectStates sends various state information to bosun with collect.
func (s *Schedule) CollectStates() {
// [AlertName][Severity]Count
Expand Down Expand Up @@ -471,7 +493,6 @@ func markDependenciesUnevaluated(events map[expr.AlertKey]*Event, deps expr.Resu
unknownCount++
}
}

}
return unevalCount, unknownCount
}
Expand Down
15 changes: 15 additions & 0 deletions collect/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,21 @@ func Sample(metric string, ts opentsdb.TagSet, v float64) error {
return nil
}

// StartTimer records the current time, and returns a function you can call to
// record the end of your action.
//
// Typical usage would be:
// done := collect.StartTimer("myMetric", opentsdb.TagSet{})
// doMyThing()
// done()
func StartTimer(metric string, ts opentsdb.TagSet) func() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider testing.Benchmark (http://stackoverflow.com/questions/8350609/how-do-you-time-a-function-in-go-and-return-its-runtime-in-milliseconds). Haven't looked into this in depth, maybe using testing here is just wrong. Up to you

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark tests are great for build-time benchmarks. It can't be used for run-time instrumentation like this is doing.

start := time.Now()
return func() {
d := time.Now().Sub(start) / time.Millisecond
Sample(metric, ts, float64(d))
}
}

type setMetric struct {
metric string
ts opentsdb.TagSet
Expand Down