-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetricsCollector.go
214 lines (189 loc) · 7.41 KB
/
metricsCollector.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package main
import (
"log"
"sync"
"github.com/prometheus/client_golang/prometheus"
)
var (
// Metric for tracking the last update timestamp of the Opsgenie data.
lastUpdateTimestamp = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "opsgenie_last_update_timestamp_seconds",
Help: "Timestamp of the last data update in Opsgenie exporter.",
})
// Metric for counting Opsgenie users by various characteristics such as total, blocked, and unverified.
opsgenieUsers = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "opsgenie_users",
Help: "Counts of Opsgenie users by various characteristics.",
}, []string{"key"})
// Metric for tracking the verification status of Opsgenie users. Uses 0 for unverified, 1 for verified.
opsgenieUserVerifiedStatus = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "opsgenie_user_verified_status",
Help: "Verification status of Opsgenie users. 0 for unverified, 1 for verified.",
}, []string{"username"})
// Metric for counting the total number of Opsgenie teams.
opsgenieTeamsTotal = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "opsgenie_teams_total",
Help: "Total number of Opsgenie teams.",
})
// Metric for displaying information about the Opsgenie account, such as user count, max user count, and yearly plan status.
opsgenieAccount = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "opsgenie_account",
Help: "Information about the Opsgenie account.",
}, []string{"key"})
// Metric for counting Opsgenie integrations by type.
opsgenieIntegrationsTotal = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "opsgenie_integrations_total",
Help: "Total number of Opsgenie integrations by type.",
}, []string{"type"})
// Metric for counting the total number of Opsgenie heartbeats.
opsgenieHeartbeatsTotal = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "opsgenie_heartbeats_total",
Help: "Total number of Opsgenie heartbeats.",
})
// Metric for counting the total number of enabled Opsgenie heartbeats.
opsgenieHeartbeatsEnabledTotal = prometheus.NewGauge(prometheus.GaugeOpts{
Name: "opsgenie_heartbeats_enabled_total",
Help: "Total number of enabled Opsgenie heartbeats.",
})
// Metric for indicating whether an Opsgenie heartbeat is expired or not, labeled by team.
opsgenieHeartbeatsExpired = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "opsgenie_heartbeats_expired",
Help: "Indicates whether an Opsgenie heartbeat is expired (1) or not (0), labeled by team.",
}, []string{"team"})
)
func init() {
// Register the metrics with Prometheus client to start collecting them.
prometheus.MustRegister(lastUpdateTimestamp)
prometheus.MustRegister(opsgenieUsers)
prometheus.MustRegister(opsgenieUserVerifiedStatus)
prometheus.MustRegister(opsgenieTeamsTotal)
prometheus.MustRegister(opsgenieAccount)
prometheus.MustRegister(opsgenieIntegrationsTotal)
prometheus.MustRegister(opsgenieHeartbeatsTotal)
prometheus.MustRegister(opsgenieHeartbeatsEnabledTotal)
prometheus.MustRegister(opsgenieHeartbeatsExpired)
}
// Helper function to convert a bool to float64 since Prometheus metrics need to be numerical.
func boolToFloat64(b bool) float64 {
if b {
return 1.0
}
return 0.0
}
// updateMetrics concurrently updates various Prometheus metrics based on data fetched from Opsgenie.
func updateMetrics(client *OpsgenieClient) {
var wg sync.WaitGroup
wg.Add(5) // Waiting for five operations: users, teams, account, integrations, and heartbeats.
// Fetch and update user-related metrics in a goroutine.
go func() {
defer wg.Done() // Ensure the WaitGroup counter decreases on goroutine completion.
users, err := client.ListUsers()
if err != nil {
log.Printf("Error fetching users: %v", err)
return
}
var total, blocked, unverified int
// Iterate through users to count total, blocked, and unverified users.
for _, user := range users {
total++
if user.Blocked {
blocked++
}
if !user.Verified {
unverified++
}
}
// Set the Prometheus gauge values for users metrics.
opsgenieUsers.With(prometheus.Labels{"key": "total"}).Set(float64(total))
opsgenieUsers.With(prometheus.Labels{"key": "blocked"}).Set(float64(blocked))
opsgenieUsers.With(prometheus.Labels{"key": "unverified"}).Set(float64(unverified))
// Additionally, set the verification status for each user.
for _, user := range users {
verifiedStatus := 1
if !user.Verified {
verifiedStatus = 0
opsgenieUserVerifiedStatus.WithLabelValues(user.Username).Set(float64(verifiedStatus))
}
}
}()
// Fetch and update teams-related metrics in a goroutine.
go func() {
defer wg.Done()
teams, err := client.ListTeams()
if err != nil {
log.Printf("Error fetching teams: %v", err)
return
}
// Set the total number of teams in a Prometheus gauge.
opsgenieTeamsTotal.Set(float64(len(teams)))
}()
// Concurrently fetch account information and update account-related metrics.
go func() {
defer wg.Done()
accountInfo, err := client.GetAccountInfo()
if err != nil {
log.Printf("Error fetching account info: %v", err)
return
}
// Set metrics based on the fetched account information.
opsgenieAccount.With(prometheus.Labels{"key": "userCount"}).Set(float64(accountInfo.Data.UserCount))
opsgenieAccount.With(prometheus.Labels{"key": "maxUserCount"}).Set(float64(accountInfo.Data.Plan.MaxUserCount))
opsgenieAccount.With(prometheus.Labels{"key": "isYearly"}).Set(boolToFloat64(accountInfo.Data.Plan.IsYearly))
}()
// Fetch and update integrations-related metrics in a goroutine.
go func() {
defer wg.Done()
integrations, err := client.ListIntegrations()
if err != nil {
log.Printf("Error fetching integrations: %v", err)
return
}
// Count and set the number of integrations by type.
typeCounts := make(map[string]int)
for _, integration := range integrations {
typeCounts[integration.Type]++
}
for integrationType, count := range typeCounts {
opsgenieIntegrationsTotal.WithLabelValues(integrationType).Set(float64(count))
}
}()
// Concurrently fetch heartbeats information and update heartbeats-related metrics.
go func() {
defer wg.Done()
heartbeats, err := client.ListHeartbeats()
if err != nil {
log.Printf("Error fetching heartbeats: %v", err)
return
}
var enabledCount, totalHeartbeats int
expiredAndEnabledCountByTeam := make(map[string]int)
// Iterate through heartbeats to count enabled and identify expired ones by team.
for _, hb := range heartbeats {
totalHeartbeats++
detail, err := client.GetHeartbeatDetail(hb.Name)
if err != nil {
log.Printf("Error fetching heartbeat detail for %s: %v", hb.Name, err)
continue
}
if detail.Enabled {
enabledCount++
if detail.Expired {
teamName := detail.OwnerTeam.Name
if teamName == "" {
teamName = "no_team" // Default value for heartbeats without a team.
}
expiredAndEnabledCountByTeam[teamName]++
}
}
}
// Update metrics for enabled and total heartbeats.
opsgenieHeartbeatsEnabledTotal.Set(float64(enabledCount))
// Update metrics for expired heartbeats by team.
for team, count := range expiredAndEnabledCountByTeam {
opsgenieHeartbeatsExpired.WithLabelValues(team).Set(float64(count))
}
opsgenieHeartbeatsTotal.Set(float64(totalHeartbeats))
}()
wg.Wait() // Wait for all goroutines to complete before updating the last update timestamp.
lastUpdateTimestamp.SetToCurrentTime() // Update the timestamp metric to the current time after metrics updates.
}