This repository has been archived by the owner on Nov 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
monitoring.go
128 lines (109 loc) · 3.52 KB
/
monitoring.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"fmt"
"strings"
"time"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
)
const (
// NagiosOk return the Nagios OK code (see https://nagios-plugins.org/doc/guidelines.html#AEN78)
NagiosOk = 0
// NagiosWarning return the Nagios WARNING code (see https://nagios-plugins.org/doc/guidelines.html#AEN78)
NagiosWarning = 1
// NagiosCritical return the Nagios CRITICAL code (see https://nagios-plugins.org/doc/guidelines.html#AEN78)
NagiosCritical = 2
// NagiosUnknown return the Nagios UNKNOWN code (see https://nagios-plugins.org/doc/guidelines.html#AEN78)
NagiosUnknown = 3
)
// MonitoringResult to store result of Nagios checks
type MonitoringResult struct {
ShopName string
Message string
ReturnCode int
}
// String returns a string to print a MonitoringResult nicely
func (m MonitoringResult) String() string {
return fmt.Sprintf("%s %s (rc = %d)", m.ShopName, m.Message, m.ReturnCode)
}
// ReturnCodeString returns a string to print a ReturnCode nicely
func ReturnCodeString(rc int) string {
switch rc {
case NagiosOk:
return "OK"
case NagiosWarning:
return "WARN"
case NagiosCritical:
return "CRIT"
default:
return "UNK"
}
}
// FormatMonitoringResults to print a list of MonitoringResult nicely
func FormatMonitoringResults(results []MonitoringResult) string {
var s []string
for _, result := range results {
s = append(s, fmt.Sprintf("%s %s", result.ShopName, result.Message))
}
return strings.Join(s, ", ")
}
// Monitor will check for last execution time for each shop and return either
// a warning or critical alert when the threshold has been reached
func Monitor(db *gorm.DB, warningTimeout int, criticalTimeout int) (rc int) {
// Find date and time thresholds
warningTime := time.Now().Add(-time.Duration(warningTimeout) * time.Second)
criticalTime := time.Now().Add(-time.Duration(criticalTimeout) * time.Second)
// Map to sort monitoring result by status code
resultMap := make(map[int][]MonitoringResult)
// List shops
var shops []Shop
trx := db.Find(&shops)
if trx.Error != nil {
fmt.Printf("%s\n", trx.Error)
return NagiosUnknown
}
for _, shop := range shops {
result := MonitoringResult{
ShopName: shop.Name,
ReturnCode: NagiosOk,
}
// Fetch last execution time
var product Product
trx := db.Where(Product{ShopID: shop.ID}).Order("updated_at desc").First(&product)
if trx.Error == gorm.ErrRecordNotFound {
result.Message = "has not been updated"
result.ReturnCode = NagiosCritical
resultMap[NagiosCritical] = append(resultMap[result.ReturnCode], result)
continue
}
if trx.Error != nil {
fmt.Printf("%s\n", trx.Error)
return NagiosUnknown
}
// Compare to thresholds and add to result map
diff := int(time.Now().Sub(product.UpdatedAt.Local()).Seconds())
result.Message = fmt.Sprintf("updated %d seconds ago", diff)
if product.UpdatedAt.Before(criticalTime) {
result.ReturnCode = NagiosCritical
} else if product.UpdatedAt.Before(warningTime) {
result.ReturnCode = NagiosWarning
} else {
}
log.Info(result)
resultMap[result.ReturnCode] = append(resultMap[result.ReturnCode], result)
}
var message string
if len(resultMap[NagiosWarning]) > 0 {
rc = NagiosWarning
message = FormatMonitoringResults(resultMap[NagiosWarning])
} else if len(resultMap[NagiosCritical]) > 0 {
rc = NagiosCritical
message = FormatMonitoringResults(resultMap[NagiosCritical])
} else {
rc = NagiosOk
message = "All shops have been updated recently"
}
// Print output
fmt.Printf("%s - %s\n", ReturnCodeString(rc), message)
return
}