Skip to content

Commit 371636c

Browse files
yhabteabjulianbrost
andcommitted
Move currentIncidents to incidents.go file
Co-authored-by: Julian Brost <[email protected]>
1 parent 50f3044 commit 371636c

File tree

3 files changed

+134
-5
lines changed

3 files changed

+134
-5
lines changed

internal/incident/history.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/icinga/icinga-notifications/internal/rule"
88
"github.com/icinga/icinga-notifications/internal/utils"
99
"github.com/icinga/icingadb/pkg/types"
10-
"log"
1110
"time"
1211
)
1312

@@ -101,7 +100,7 @@ func (i *Incident) AddRecipient(escalation *rule.Escalation, eventId int64) erro
101100
oldRole := state.Role
102101
state.Role = newRole
103102

104-
log.Printf("[%s %s] contact %q role changed from %s to %s", i.Object.DisplayName(), i.String(), r, state.Role.String(), newRole.String())
103+
i.logger.Infof("[%s %s] contact %q role changed from %s to %s", i.Object.DisplayName(), i.String(), r, state.Role.String(), newRole.String())
105104

106105
hr := &HistoryRow{
107106
IncidentID: i.incidentRowID,

internal/incident/incident.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,21 @@ func (i *Incident) processIncidentAndSourceSeverity(ev event.Event, created bool
222222
i.RecoveredAt = time.Now()
223223
i.logger.Infof("[%s %s] all sources recovered, closing incident", i.Object.DisplayName(), i.String())
224224

225+
RemoveCurrent(i.Object)
226+
227+
incidentRow := &IncidentRow{ID: i.incidentRowID, RecoveredAt: types.UnixMilli(i.RecoveredAt)}
228+
_, err := i.db.NamedExec(`UPDATE "incident" SET "recovered_at" = :recovered_at WHERE id = :id`, incidentRow)
229+
if err != nil {
230+
return fmt.Errorf("failed to update current incident: %w", err)
231+
}
232+
225233
history = &HistoryRow{
226234
EventID: utils.ToDBInt(ev.ID),
227235
Time: types.UnixMilli(i.RecoveredAt),
228236
Type: Closed,
229237
}
230-
if err = RemoveCurrent(i.Object, history); err != nil {
231-
i.logger.Errorln(err)
232-
238+
_, err = i.AddHistory(history, false)
239+
if err != nil {
233240
return err
234241
}
235242
}

internal/incident/incidents.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package incident
2+
3+
import (
4+
"database/sql"
5+
"fmt"
6+
"github.com/icinga/icingadb/pkg/icingadb"
7+
"github.com/icinga/icingadb/pkg/logging"
8+
"github.com/icinga/noma/internal/config"
9+
"github.com/icinga/noma/internal/event"
10+
"github.com/icinga/noma/internal/object"
11+
"github.com/icinga/noma/internal/recipient"
12+
"sync"
13+
)
14+
15+
var (
16+
currentIncidents = make(map[*object.Object]*Incident)
17+
currentIncidentsMu sync.Mutex
18+
)
19+
20+
func GetCurrent(db *icingadb.DB, obj *object.Object, logger *logging.Logger, runtimeConfig *config.RuntimeConfig, create bool) (*Incident, bool, error) {
21+
currentIncidentsMu.Lock()
22+
defer currentIncidentsMu.Unlock()
23+
24+
created := false
25+
currentIncident := currentIncidents[obj]
26+
27+
if currentIncident == nil {
28+
ir := &IncidentRow{}
29+
incident := &Incident{Object: obj, db: db, logger: logger, runtimeConfig: runtimeConfig}
30+
incident.SeverityBySource = make(map[int64]event.Severity)
31+
incident.EscalationState = make(map[escalationID]*EscalationState)
32+
incident.Recipients = make(map[recipient.Key]*RecipientState)
33+
34+
err := db.QueryRowx(db.Rebind(db.BuildSelectStmt(ir, ir)+` WHERE "object_id" = ? AND "recovered_at" IS NULL`), obj.ID).StructScan(ir)
35+
if err != nil && err != sql.ErrNoRows {
36+
return nil, false, fmt.Errorf("incident query failed with: %w", err)
37+
} else if err == nil {
38+
incident.incidentRowID = ir.ID
39+
incident.StartedAt = ir.StartedAt.Time()
40+
41+
sourceSeverity := &SourceSeverity{IncidentID: ir.ID}
42+
var sources []SourceSeverity
43+
err := db.Select(
44+
&sources,
45+
db.Rebind(db.BuildSelectStmt(sourceSeverity, sourceSeverity)+` WHERE "incident_id" = ? AND "severity" != ?`),
46+
ir.ID, event.SeverityOK,
47+
)
48+
if err != nil {
49+
return nil, false, fmt.Errorf("failed to fetch incident sources Severity: %w", err)
50+
}
51+
52+
for _, source := range sources {
53+
incident.SeverityBySource[source.SourceID] = source.Severity
54+
}
55+
56+
state := &EscalationState{}
57+
var states []*EscalationState
58+
err = db.Select(&states, db.Rebind(db.BuildSelectStmt(state, state)+` WHERE "incident_id" = ?`), ir.ID)
59+
if err != nil {
60+
return nil, false, fmt.Errorf("failed to fetch incident rule escalation state: %w", err)
61+
}
62+
63+
for _, state := range states {
64+
incident.EscalationState[state.RuleEscalationID] = state
65+
}
66+
67+
currentIncident = incident
68+
}
69+
70+
if create && currentIncident == nil {
71+
created = true
72+
currentIncident = incident
73+
}
74+
75+
if currentIncident != nil {
76+
currentIncidents[obj] = currentIncident
77+
}
78+
}
79+
80+
if !created && currentIncident != nil {
81+
currentIncident.Lock()
82+
defer currentIncident.Unlock()
83+
84+
contact := &ContactRow{}
85+
var contacts []*ContactRow
86+
err := db.Select(&contacts, db.Rebind(db.BuildSelectStmt(contact, contact)+` WHERE "incident_id" = ?`), currentIncident.ID())
87+
if err != nil {
88+
return nil, false, fmt.Errorf("failed to fetch incident recipients: %w", err)
89+
}
90+
91+
recipients := make(map[recipient.Key]*RecipientState)
92+
for _, contact := range contacts {
93+
recipients[contact.Key] = &RecipientState{Role: contact.Role}
94+
}
95+
96+
currentIncident.Recipients = recipients
97+
}
98+
99+
return currentIncident, created, nil
100+
}
101+
102+
func RemoveCurrent(obj *object.Object) {
103+
currentIncidentsMu.Lock()
104+
defer currentIncidentsMu.Unlock()
105+
106+
currentIncident := currentIncidents[obj]
107+
108+
if currentIncident != nil {
109+
delete(currentIncidents, obj)
110+
}
111+
}
112+
113+
// GetCurrentIncidents returns a map of all incidents for debugging purposes.
114+
func GetCurrentIncidents() map[int64]*Incident {
115+
currentIncidentsMu.Lock()
116+
defer currentIncidentsMu.Unlock()
117+
118+
m := make(map[int64]*Incident)
119+
for _, incident := range currentIncidents {
120+
m[incident.incidentRowID] = incident
121+
}
122+
return m
123+
}

0 commit comments

Comments
 (0)