mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-07 00:37:36 +00:00
218 lines
5.7 KiB
Go
218 lines
5.7 KiB
Go
package alerts
|
|
|
|
func activeAlertStorageKey(alert *Alert, fallback string) string {
|
|
if fallback == "" && alert == nil {
|
|
return ""
|
|
}
|
|
if alert != nil {
|
|
backfillCanonicalIdentity(alert)
|
|
if alert.CanonicalState != "" {
|
|
return alert.CanonicalState
|
|
}
|
|
if alert.ID != "" {
|
|
return alert.ID
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func effectiveAlertID(alert *Alert, fallback string) string {
|
|
if alert != nil {
|
|
backfillCanonicalIdentity(alert)
|
|
if alert.CanonicalState != "" {
|
|
return alert.CanonicalState
|
|
}
|
|
if alert.ID != "" {
|
|
return alert.ID
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func (m *Manager) registerActiveAlertAliasNoLock(storageKey string, alert *Alert) {
|
|
if m == nil || alert == nil || storageKey == "" {
|
|
return
|
|
}
|
|
if m.activeAlertAlias == nil {
|
|
m.activeAlertAlias = make(map[string]string)
|
|
}
|
|
backfillCanonicalIdentity(alert)
|
|
if alias := effectiveAlertID(alert, ""); alias != "" && alias != storageKey {
|
|
m.activeAlertAlias[alias] = storageKey
|
|
}
|
|
if alert.CanonicalState != "" && alert.CanonicalState != storageKey {
|
|
m.activeAlertAlias[alert.CanonicalState] = storageKey
|
|
}
|
|
}
|
|
|
|
func (m *Manager) resolveActiveAlertKeyNoLock(id string) (string, bool) {
|
|
if _, ok := m.activeAlerts[id]; ok {
|
|
return id, true
|
|
}
|
|
key, ok := m.activeAlertAlias[id]
|
|
if !ok {
|
|
return "", false
|
|
}
|
|
if _, exists := m.activeAlerts[key]; !exists {
|
|
delete(m.activeAlertAlias, id)
|
|
return "", false
|
|
}
|
|
return key, true
|
|
}
|
|
|
|
func (m *Manager) resolveActiveAlertKeyByCanonicalStateNoLock(id string) (string, bool) {
|
|
for storageKey, alert := range m.activeAlerts {
|
|
if alert == nil {
|
|
continue
|
|
}
|
|
backfillCanonicalIdentity(alert)
|
|
if alert.CanonicalState != id {
|
|
continue
|
|
}
|
|
if m.activeAlertAlias == nil {
|
|
m.activeAlertAlias = make(map[string]string)
|
|
}
|
|
m.activeAlertAlias[id] = storageKey
|
|
return storageKey, true
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func (m *Manager) getActiveAlertNoLock(id string) (*Alert, bool) {
|
|
key, ok := m.resolveActiveAlertKeyNoLock(id)
|
|
if !ok {
|
|
key, ok = m.resolveActiveAlertKeyByCanonicalStateNoLock(id)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
}
|
|
alert := m.activeAlerts[key]
|
|
if alert == nil {
|
|
return nil, false
|
|
}
|
|
backfillCanonicalIdentity(alert)
|
|
return alert, true
|
|
}
|
|
|
|
func (m *Manager) hasActiveAlertNoLock(id string) bool {
|
|
if _, ok := m.resolveActiveAlertKeyNoLock(id); ok {
|
|
return true
|
|
}
|
|
_, ok := m.resolveActiveAlertKeyByCanonicalStateNoLock(id)
|
|
return ok
|
|
}
|
|
|
|
func (m *Manager) setActiveAlertNoLock(storageKey string, alert *Alert) {
|
|
if storageKey == "" || alert == nil {
|
|
return
|
|
}
|
|
backfillCanonicalIdentity(alert)
|
|
requestedKey := storageKey
|
|
storageKey = activeAlertStorageKey(alert, storageKey)
|
|
for _, staleKey := range []string{requestedKey, alert.ID, alert.CanonicalState} {
|
|
if staleKey == "" || staleKey == storageKey {
|
|
continue
|
|
}
|
|
if existing, ok := m.activeAlerts[staleKey]; ok {
|
|
delete(m.activeAlerts, staleKey)
|
|
m.unregisterActiveAlertAliasNoLock(staleKey, existing)
|
|
}
|
|
}
|
|
m.activeAlerts[storageKey] = alert
|
|
m.registerActiveAlertAliasNoLock(storageKey, alert)
|
|
}
|
|
|
|
func (m *Manager) unregisterActiveAlertAliasNoLock(storageKey string, alert *Alert) {
|
|
if m == nil || storageKey == "" {
|
|
return
|
|
}
|
|
if alert != nil {
|
|
backfillCanonicalIdentity(alert)
|
|
if alias := effectiveAlertID(alert, ""); alias != "" && alias != storageKey {
|
|
delete(m.activeAlertAlias, alias)
|
|
}
|
|
if alert.CanonicalState != "" && alert.CanonicalState != storageKey {
|
|
delete(m.activeAlertAlias, alert.CanonicalState)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *Manager) registerResolvedAliasUnlocked(storageKey string, resolved *ResolvedAlert) {
|
|
if m == nil || resolved == nil || resolved.Alert == nil || storageKey == "" {
|
|
return
|
|
}
|
|
if m.resolvedAlias == nil {
|
|
m.resolvedAlias = make(map[string]string)
|
|
}
|
|
backfillCanonicalIdentity(resolved.Alert)
|
|
if alias := effectiveAlertID(resolved.Alert, ""); alias != "" && alias != storageKey {
|
|
m.resolvedAlias[alias] = storageKey
|
|
}
|
|
if resolved.Alert.CanonicalState != "" && resolved.Alert.CanonicalState != storageKey {
|
|
m.resolvedAlias[resolved.Alert.CanonicalState] = storageKey
|
|
}
|
|
}
|
|
|
|
func (m *Manager) unregisterResolvedAliasUnlocked(storageKey string, resolved *ResolvedAlert) {
|
|
if m == nil || storageKey == "" {
|
|
return
|
|
}
|
|
if resolved != nil && resolved.Alert != nil {
|
|
backfillCanonicalIdentity(resolved.Alert)
|
|
if alias := effectiveAlertID(resolved.Alert, ""); alias != "" && alias != storageKey {
|
|
delete(m.resolvedAlias, alias)
|
|
}
|
|
if resolved.Alert.CanonicalState != "" && resolved.Alert.CanonicalState != storageKey {
|
|
delete(m.resolvedAlias, resolved.Alert.CanonicalState)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *Manager) removeResolvedAlertUnlocked(id string) (*ResolvedAlert, bool) {
|
|
resolved, ok := m.getResolvedAlertNoLock(id)
|
|
if !ok || resolved == nil {
|
|
return nil, false
|
|
}
|
|
|
|
storageKey := id
|
|
if resolved.Alert != nil {
|
|
storageKey = activeAlertStorageKey(resolved.Alert, id)
|
|
}
|
|
if key, exists := m.resolvedAlias[id]; exists {
|
|
storageKey = key
|
|
}
|
|
|
|
delete(m.recentlyResolved, storageKey)
|
|
m.unregisterResolvedAliasUnlocked(storageKey, resolved)
|
|
return resolved, true
|
|
}
|
|
|
|
func (m *Manager) getResolvedAlertNoLock(id string) (*ResolvedAlert, bool) {
|
|
if resolved, ok := m.recentlyResolved[id]; ok && resolved != nil {
|
|
return resolved, true
|
|
}
|
|
key, ok := m.resolvedAlias[id]
|
|
if !ok {
|
|
for storageKey, resolved := range m.recentlyResolved {
|
|
if resolved == nil || resolved.Alert == nil {
|
|
continue
|
|
}
|
|
backfillCanonicalIdentity(resolved.Alert)
|
|
if resolved.Alert.CanonicalState != id {
|
|
continue
|
|
}
|
|
if m.resolvedAlias == nil {
|
|
m.resolvedAlias = make(map[string]string)
|
|
}
|
|
m.resolvedAlias[id] = storageKey
|
|
return resolved, true
|
|
}
|
|
return nil, false
|
|
}
|
|
resolved, exists := m.recentlyResolved[key]
|
|
if !exists || resolved == nil {
|
|
delete(m.resolvedAlias, id)
|
|
return nil, false
|
|
}
|
|
return resolved, true
|
|
}
|