master
go 154 lines 3.45 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package nagios
4
5 import (
6 "strings"
7 "time"
8 )
9
10 type collectState struct {
11 nextAnniversary time.Time
12 nextDue time.Time
13
14 serviceState string
15 jobState string
16 softAttempts int
17 retrying bool
18 maxAttempts int
19
20 lastPerfValues []perfValueMeasureSet
21 lastPerfThresholdStates []perfThresholdStateSet
22 }
23
24 func newCollectState(now time.Time, job JobConfig) collectState {
25 return collectState{
26 nextAnniversary: now,
27 nextDue: now,
28 serviceState: nagiosStateUnknown,
29 jobState: nagiosStateUnknown,
30 maxAttempts: max(job.MaxCheckAttempts, 1),
31 }
32 }
33
34 func (s *collectState) due(now time.Time) bool {
35 return s.nextDue.IsZero() || !s.nextDue.After(now)
36 }
37
38 func (s *collectState) currentServiceState() string {
39 if s == nil || s.serviceState == "" {
40 return nagiosStateUnknown
41 }
42 return s.serviceState
43 }
44
45 func (s *collectState) currentJobState() string {
46 if s == nil || s.jobState == "" {
47 return nagiosStateUnknown
48 }
49 return s.jobState
50 }
51
52 func (s *collectState) isRetrying() bool {
53 return s != nil && s.retrying
54 }
55
56 func (s *collectState) currentAttempt() int {
57 if s == nil {
58 return 1
59 }
60 if strings.EqualFold(s.serviceState, nagiosStateOK) || s.serviceState == "" {
61 return 1
62 }
63 attempt := s.softAttempts
64 if attempt <= 0 {
65 attempt = 1
66 }
67 if s.retrying {
68 attempt++
69 }
70 if attempt > s.maxAttempts {
71 return s.maxAttempts
72 }
73 return attempt
74 }
75
76 func (s *collectState) macroState() macroState {
77 return macroState{
78 ServiceState: s.currentServiceState(),
79 ServiceAttempt: s.currentAttempt(),
80 ServiceMaxAttempts: s.maxAttempts,
81 }
82 }
83
84 func (s *collectState) recordResult(serviceState, jobState string) {
85 serviceState = normalizeState(serviceState)
86 jobState = normalizeJobState(jobState)
87 if serviceState == nagiosStateOK {
88 s.softAttempts = 0
89 s.retrying = false
90 } else {
91 s.softAttempts++
92 if s.softAttempts >= s.maxAttempts {
93 s.retrying = false
94 } else {
95 s.retrying = true
96 }
97 }
98 s.serviceState = serviceState
99 s.jobState = jobState
100 }
101
102 func (s *collectState) recordPeriodBlocked() {
103 s.jobState = jobStatePaused
104 for i := range s.lastPerfThresholdStates {
105 s.lastPerfThresholdStates[i].state = ""
106 }
107 }
108
109 func (s *collectState) rememberPerf(result perfRouteResult) {
110 s.lastPerfValues = append(s.lastPerfValues[:0], result.values...)
111 s.lastPerfThresholdStates = append(s.lastPerfThresholdStates[:0], result.thresholdStates...)
112 }
113
114 func (s *collectState) perfValueSets() []perfValueMeasureSet {
115 return s.lastPerfValues
116 }
117
118 func (s *collectState) perfThresholdStates() []perfThresholdStateSet {
119 return s.lastPerfThresholdStates
120 }
121
122 func (s *collectState) completeRun(now time.Time, serviceState, jobState string, perf perfRouteResult, job JobConfig) {
123 s.recordResult(serviceState, jobState)
124 s.rememberPerf(perf)
125 if s.retrying {
126 s.scheduleRetry(now, job.RetryInterval.Duration())
127 return
128 }
129 s.scheduleRegular(now, s.nextAnniversary, job.CheckInterval.Duration())
130 }
131
132 func normalizeState(state string) string {
133 switch strings.ToUpper(strings.TrimSpace(state)) {
134 case nagiosStateOK:
135 return nagiosStateOK
136 case nagiosStateWarning:
137 return nagiosStateWarning
138 case nagiosStateCritical:
139 return nagiosStateCritical
140 default:
141 return nagiosStateUnknown
142 }
143 }
144
145 func normalizeJobState(state string) string {
146 switch strings.ToUpper(strings.TrimSpace(state)) {
147 case jobStateTimeout:
148 return jobStateTimeout
149 case jobStatePaused:
150 return jobStatePaused
151 default:
152 return normalizeState(state)
153 }
154 }