Skip to content

Commit

Permalink
fix bug where duration of alert was incorrect when restoring alert state
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanielc committed Feb 15, 2017
1 parent d9f8ac4 commit 228915b
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 7 deletions.
18 changes: 11 additions & 7 deletions alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,10 +464,12 @@ func (a *AlertNode) runAlert([]byte) error {
currentLevel = state.currentLevel()
} else {
// Check for previous state
currentLevel = a.restoreEventState(id)
var triggered time.Time
currentLevel, triggered = a.restoreEventState(id)
if currentLevel != alert.OK {
// Update the state with the restored state
a.updateState(p.Time, currentLevel, p.Group)
state = a.updateState(p.Time, currentLevel, p.Group)
state.triggered(triggered)
}
}
l := a.determineLevel(p.Time, p.Fields, p.Tags, currentLevel)
Expand Down Expand Up @@ -554,10 +556,12 @@ func (a *AlertNode) runAlert([]byte) error {
currentLevel = state.currentLevel()
} else {
// Check for previous state
currentLevel = a.restoreEventState(id)
var triggered time.Time
currentLevel, triggered = a.restoreEventState(id)
if currentLevel != alert.OK {
// Update the state with the restored state
a.updateState(b.TMax, currentLevel, b.Group)
state = a.updateState(b.TMax, currentLevel, b.Group)
state.triggered(triggered)
}
}
for i, p := range b.Points {
Expand Down Expand Up @@ -683,7 +687,7 @@ func (a *AlertNode) hasTopic() bool {
return a.topic != ""
}

func (a *AlertNode) restoreEventState(id string) alert.Level {
func (a *AlertNode) restoreEventState(id string) (alert.Level, time.Time) {
var topicState, anonTopicState alert.EventState
var anonFound, topicFound bool
// Check for previous state on anonTopic
Expand Down Expand Up @@ -714,9 +718,9 @@ func (a *AlertNode) restoreEventState(id string) alert.Level {
} // else nothing was found, nothing to do
}
if anonFound {
return anonTopicState.Level
return anonTopicState.Level, anonTopicState.Time
}
return topicState.Level
return topicState.Level, topicState.Time
}

func (a *AlertNode) handleEvent(event alert.Event) {
Expand Down
115 changes: 115 additions & 0 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7766,6 +7766,121 @@ stream
}
}

func TestServer_Alert_Duration(t *testing.T) {
// Setup test TCP server
ts, err := alerttest.NewTCPServer()
if err != nil {
t.Fatal(err)
}
defer ts.Close()

// Create default config
c := NewConfig()
s := OpenServer(c)
cli := Client(s)
defer s.Close()

tick := `
stream
|from()
.measurement('alert')
|alert()
.id('id')
.message('message')
.details('details')
.crit(lambda: "value" > 1.0)
.tcp('` + ts.Addr + `')
`

if _, err := cli.CreateTask(client.CreateTaskOptions{
ID: "testAlertHandlers",
Type: client.StreamTask,
DBRPs: []client.DBRP{{
Database: "mydb",
RetentionPolicy: "myrp",
}},
TICKscript: tick,
Status: client.Enabled,
}); err != nil {
t.Fatal(err)
}

// Write point
point := "alert value=2 0000000000"
v := url.Values{}
v.Add("precision", "s")
s.MustWrite("mydb", "myrp", point, v)

// Restart the server
s.Restart()

topic := "main:testAlertHandlers:alert2"
l := cli.TopicEventsLink(topic)
expTopicEvents := client.TopicEvents{
Link: l,
Topic: topic,
Events: []client.TopicEvent{{
Link: client.Link{Relation: client.Self, Href: fmt.Sprintf("/kapacitor/v1preview/alerts/topics/%s/events/id", topic)},
ID: "id",
State: client.EventState{
Message: "message",
Details: "details",
Time: time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC),
Duration: 0,
Level: "CRITICAL",
},
}},
}

te, err := cli.ListTopicEvents(l, nil)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(te, expTopicEvents) {
t.Errorf("unexpected topic events for anonymous topic:\ngot\n%+v\nexp\n%+v\n", te, expTopicEvents)
}
event, err := cli.TopicEvent(expTopicEvents.Events[0].Link)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(event, expTopicEvents.Events[0]) {
t.Errorf("unexpected topic event for anonymous topic:\ngot\n%+v\nexp\n%+v\n", event, expTopicEvents.Events[0])
}

// Write point
point = "alert value=3 0000000001"
v = url.Values{}
v.Add("precision", "s")
s.MustWrite("mydb", "myrp", point, v)

// Restart the server
s.Restart()

expTopicEvents = client.TopicEvents{
Link: l,
Topic: topic,
Events: []client.TopicEvent{{
Link: client.Link{Relation: client.Self, Href: fmt.Sprintf("/kapacitor/v1preview/alerts/topics/%s/events/id", topic)},
ID: "id",
State: client.EventState{
Message: "message",
Details: "details",
Time: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC),
Duration: client.Duration(time.Second),
Level: "CRITICAL",
},
}},
}

te, err = cli.ListTopicEvents(l, nil)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(te, expTopicEvents) {
t.Errorf("unexpected topic events for anonymous topic after second point:\ngot\n%+v\nexp\n%+v\n", te, expTopicEvents)
}
}

func TestServer_AlertAnonTopic(t *testing.T) {
// Setup test TCP server
ts, err := alerttest.NewTCPServer()
Expand Down

0 comments on commit 228915b

Please sign in to comment.