Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b5d0581

Browse files
committed
Use CachedGaugeVec
1 parent 3a8e4e6 commit b5d0581

File tree

2 files changed

+100
-20
lines changed

2 files changed

+100
-20
lines changed

coderd/prometheusmetrics/collector.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package prometheusmetrics
2+
3+
import (
4+
"sync"
5+
6+
"github.com/prometheus/client_golang/prometheus"
7+
)
8+
9+
type CachedGaugeVec struct {
10+
m sync.Mutex
11+
12+
gaugeVec *prometheus.GaugeVec
13+
records []vectorRecord
14+
}
15+
16+
var _ prometheus.Collector = new(CachedGaugeVec)
17+
18+
type VectorOperation int
19+
20+
const (
21+
VectorOperationAdd VectorOperation = iota
22+
VectorOperationSet
23+
)
24+
25+
type vectorRecord struct {
26+
operation VectorOperation
27+
value float64
28+
labelValues []string
29+
}
30+
31+
func NewCachedGaugeVec(gaugeVec *prometheus.GaugeVec) *CachedGaugeVec {
32+
return &CachedGaugeVec{
33+
gaugeVec: gaugeVec,
34+
}
35+
}
36+
37+
func (v *CachedGaugeVec) Describe(desc chan<- *prometheus.Desc) {
38+
v.m.Lock()
39+
defer v.m.Unlock()
40+
41+
v.gaugeVec.Describe(desc)
42+
}
43+
44+
func (v *CachedGaugeVec) Collect(ch chan<- prometheus.Metric) {
45+
v.m.Lock()
46+
defer v.m.Unlock()
47+
48+
v.gaugeVec.Collect(ch)
49+
}
50+
51+
func (v *CachedGaugeVec) WithLabelValues(operation VectorOperation, value float64, labelValues ...string) {
52+
v.m.Lock()
53+
defer v.m.Unlock()
54+
55+
v.records = append(v.records, vectorRecord{
56+
operation: operation,
57+
value: value,
58+
labelValues: labelValues,
59+
})
60+
}
61+
62+
func (v *CachedGaugeVec) Commit() {
63+
v.m.Lock()
64+
defer v.m.Unlock()
65+
66+
v.gaugeVec.Reset()
67+
for _, record := range v.records {
68+
g := v.gaugeVec.WithLabelValues(record.labelValues...)
69+
switch record.operation {
70+
case VectorOperationAdd:
71+
g.Add(record.value)
72+
case VectorOperationSet:
73+
g.Set(record.value)
74+
default:
75+
panic("unsupported vector operation")
76+
}
77+
}
78+
79+
v.records = nil
80+
}

coderd/prometheusmetrics/prometheusmetrics.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -124,45 +124,45 @@ func Agents(ctx context.Context, logger slog.Logger, registerer prometheus.Regis
124124
duration = 1 * time.Minute
125125
}
126126

127-
agentsGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
127+
agentsGauge := NewCachedGaugeVec(prometheus.NewGaugeVec(prometheus.GaugeOpts{
128128
Namespace: "coderd",
129129
Subsystem: "agents",
130130
Name: "up",
131131
Help: "The number of active agents per workspace.",
132-
}, []string{"username", "workspace_name"})
132+
}, []string{"username", "workspace_name"}))
133133
err := registerer.Register(agentsGauge)
134134
if err != nil {
135135
return nil, err
136136
}
137137

138-
agentsConnectionsGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
138+
agentsConnectionsGauge := NewCachedGaugeVec(prometheus.NewGaugeVec(prometheus.GaugeOpts{
139139
Namespace: "coderd",
140140
Subsystem: "agents",
141141
Name: "connections",
142142
Help: "Agent connections with statuses.",
143-
}, []string{"agent_name", "username", "workspace_name", "status", "lifecycle_state", "tailnet_node"})
143+
}, []string{"agent_name", "username", "workspace_name", "status", "lifecycle_state", "tailnet_node"}))
144144
err = registerer.Register(agentsConnectionsGauge)
145145
if err != nil {
146146
return nil, err
147147
}
148148

149-
agentsConnectionLatenciesGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
149+
agentsConnectionLatenciesGauge := NewCachedGaugeVec(prometheus.NewGaugeVec(prometheus.GaugeOpts{
150150
Namespace: "coderd",
151151
Subsystem: "agents",
152152
Name: "connection_latencies_seconds",
153153
Help: "Agent connection latencies in seconds.",
154-
}, []string{"agent_id", "username", "workspace_name", "derp_region", "preferred"})
154+
}, []string{"agent_id", "username", "workspace_name", "derp_region", "preferred"}))
155155
err = registerer.Register(agentsConnectionLatenciesGauge)
156156
if err != nil {
157157
return nil, err
158158
}
159159

160-
agentsAppsGauge := prometheus.NewGaugeVec(prometheus.GaugeOpts{
160+
agentsAppsGauge := NewCachedGaugeVec(prometheus.NewGaugeVec(prometheus.GaugeOpts{
161161
Namespace: "coderd",
162162
Subsystem: "agents",
163163
Name: "apps",
164164
Help: "Agent applications with statuses.",
165-
}, []string{"agent_name", "username", "workspace_name", "app_name", "health"})
165+
}, []string{"agent_name", "username", "workspace_name", "app_name", "health"}))
166166
err = registerer.Register(agentsAppsGauge)
167167
if err != nil {
168168
return nil, err
@@ -203,35 +203,30 @@ func Agents(ctx context.Context, logger slog.Logger, registerer prometheus.Regis
203203
continue
204204
}
205205

206-
agentsGauge.Reset()
207-
agentsConnectionsGauge.Reset()
208-
agentsConnectionLatenciesGauge.Reset()
209-
agentsAppsGauge.Reset()
210-
211206
for _, workspace := range workspaceRows {
212207
user, err := db.GetUserByID(ctx, workspace.OwnerID)
213208
if err != nil {
214209
logger.Error(ctx, "can't get user", slog.F("user_id", workspace.OwnerID), slog.Error(err))
215-
agentsGauge.WithLabelValues(user.Username, workspace.Name).Add(0)
210+
agentsGauge.WithLabelValues(VectorOperationAdd, 0, user.Username, workspace.Name)
216211
continue
217212
}
218213

219214
agents, err := db.GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx, workspace.ID)
220215
if err != nil {
221216
logger.Error(ctx, "can't get workspace agents", slog.F("workspace_id", workspace.ID), slog.Error(err))
222-
agentsGauge.WithLabelValues(user.Username, workspace.Name).Add(0)
217+
agentsGauge.WithLabelValues(VectorOperationAdd, 0, user.Username, workspace.Name)
223218
continue
224219
}
225220

226221
if len(agents) == 0 {
227222
logger.Debug(ctx, "workspace agents are unavailable", slog.F("workspace_id", workspace.ID))
228-
agentsGauge.WithLabelValues(user.Username, workspace.Name).Add(0)
223+
agentsGauge.WithLabelValues(VectorOperationAdd, 0, user.Username, workspace.Name)
229224
continue
230225
}
231226

232227
for _, agent := range agents {
233228
// Collect information about agents
234-
agentsGauge.WithLabelValues(user.Username, workspace.Name).Add(1)
229+
agentsGauge.WithLabelValues(VectorOperationAdd, 1, user.Username, workspace.Name)
235230

236231
connectionStatus := agent.Status(agentInactiveDisconnectTimeout)
237232
node := (*coordinator.Load()).Node(agent.ID)
@@ -241,7 +236,7 @@ func Agents(ctx context.Context, logger slog.Logger, registerer prometheus.Regis
241236
tailnetNode = node.ID.String()
242237
}
243238

244-
agentsConnectionsGauge.WithLabelValues(agent.Name, user.Username, workspace.Name, string(connectionStatus.Status), string(agent.LifecycleState), tailnetNode).Set(1)
239+
agentsConnectionsGauge.WithLabelValues(VectorOperationSet, 1, agent.Name, user.Username, workspace.Name, string(connectionStatus.Status), string(agent.LifecycleState), tailnetNode)
245240

246241
if node == nil {
247242
logger.Debug(ctx, "can't read in-memory node for agent", slog.F("agent_id", agent.ID))
@@ -266,7 +261,7 @@ func Agents(ctx context.Context, logger slog.Logger, registerer prometheus.Regis
266261
}
267262
}
268263

269-
agentsConnectionLatenciesGauge.WithLabelValues(agent.Name, user.Username, workspace.Name, region.RegionName, fmt.Sprintf("%v", node.PreferredDERP == regionID)).Set(latency)
264+
agentsConnectionLatenciesGauge.WithLabelValues(VectorOperationSet, latency, agent.Name, user.Username, workspace.Name, region.RegionName, fmt.Sprintf("%v", node.PreferredDERP == regionID))
270265
}
271266
}
272267

@@ -278,11 +273,16 @@ func Agents(ctx context.Context, logger slog.Logger, registerer prometheus.Regis
278273
}
279274

280275
for _, app := range apps {
281-
agentsAppsGauge.WithLabelValues(agent.Name, user.Username, workspace.Name, app.DisplayName, string(app.Health)).Add(1)
276+
agentsAppsGauge.WithLabelValues(VectorOperationAdd, 1, agent.Name, user.Username, workspace.Name, app.DisplayName, string(app.Health))
282277
}
283278
}
284279
}
285280

281+
agentsGauge.Commit()
282+
agentsConnectionsGauge.Commit()
283+
agentsConnectionLatenciesGauge.Commit()
284+
agentsAppsGauge.Commit()
285+
286286
logger.Debug(ctx, "Agent metrics collection is done")
287287
metricsCollectorAgents.Observe(timer.ObserveDuration().Seconds())
288288
}

0 commit comments

Comments
 (0)