-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmetrics.go
More file actions
134 lines (120 loc) · 3.51 KB
/
Copy pathmetrics.go
File metadata and controls
134 lines (120 loc) · 3.51 KB
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
// SPDX-License-Identifier: AGPL-3.0-or-later
package server
import (
"runtime"
"time"
metrpkg "github.com/pilot-protocol/rendezvous/metrics"
)
// updateGauges reads current server state and sets gauge values on the metrics Store.
// It must be called with no locks held; it acquires s.mu.RLock internally.
func (s *Server) updateGauges(m *metrpkg.Store) {
s.mu.RLock()
defer s.mu.RUnlock()
now := time.Now()
onlineThreshold := now.Add(-s.StaleNodeThreshold())
total := len(s.nodes)
online := 0
taskExec := 0
for _, node := range s.nodes {
// Use the atomic-aware getter: heartbeat hot path updates only
// lastSeenNano (under shard.RLock), not the legacy LastSeen field.
// Reading LastSeen directly here under-counted "online" for any
// node that had heartbeated since registration but never gone
// through a slow-path operation.
if node.GetLastSeen().After(onlineThreshold) {
online++
}
if node.TaskExec {
taskExec++
}
}
m.NodesTotal.Set(float64(total))
m.NodesOnline.Set(float64(online))
m.TrustLinks.Set(float64(s.trust.Count()))
m.TaskExecutors.Set(float64(taskExec))
m.UptimeSeconds.Set(now.Sub(s.startTime).Seconds())
// Enterprise gauges
netTotal := 0
netEnterprise := 0
var netSnaps []metrpkg.NetworkMetricSnapshot
for _, n := range s.networks {
if n.ID == 0 {
continue // skip backbone
}
netTotal++
if n.Enterprise {
netEnterprise++
}
snap := metrpkg.NetworkMetricSnapshot{
Name: n.Name,
Members: len(n.Members),
Enterprise: n.Enterprise,
PolicySet: n.Policy.MaxMembers > 0 || len(n.Policy.AllowedPorts) > 0,
}
for _, role := range n.MemberRoles {
switch role {
case RoleOwner:
snap.Owners++
case RoleAdmin:
snap.Admins++
}
}
netSnaps = append(netSnaps, snap)
}
m.NetworksTotal.Set(float64(netTotal))
m.NetworksEnterprise.Set(float64(netEnterprise))
m.SetNetworkMetrics(netSnaps)
pendingInvites := 0
for _, invites := range s.inviteInbox {
pendingInvites += len(invites)
}
m.InvitesPending.Set(float64(pendingInvites))
// Enterprise status
if s.identity.GetIDPConfig() != nil {
m.IdpConfigured.Set(1)
} else {
m.IdpConfigured.Set(0)
}
if s.webhook != nil {
m.WebhookConfigured.Set(1)
} else {
m.WebhookConfigured.Set(0)
}
if s.auditStore.ExporterConfig() != nil {
m.AuditExportActive.Set(1)
} else {
m.AuditExportActive.Set(0)
}
dirSynced := 0
for range s.rbacPreAssign {
dirSynced++
}
m.DirectorySynced.Set(float64(dirSynced))
// Saturation observability — capture via trust.InboxSize (separate from s.mu).
// runtime.NumGoroutine is lock-free.
m.RuntimeGoroutines.Set(float64(runtime.NumGoroutine()))
m.RuntimeConnectionsTCP.Set(float64(s.ConnCount()))
hi, hr := s.trust.InboxSize()
m.HandshakeInboxSize.Set(float64(hi))
m.HandshakeRespSize.Set(float64(hr))
// list_nodes cache counters — sum legacy backbone-admin cache + all
// per-network caches so the gauge reflects real activity.
var totalHits, totalWaits, totalRebuilds uint64
s.listNodesCache.Mu.Lock()
totalHits += s.listNodesCache.CacheHits
totalWaits += s.listNodesCache.CacheWaits
totalRebuilds += s.listNodesCache.CacheRebuilds
s.listNodesCache.Mu.Unlock()
s.listNodesPerNetMu.Lock()
for _, c := range s.listNodesPerNet {
c.Mu.Lock()
totalHits += c.CacheHits
totalWaits += c.CacheWaits
totalRebuilds += c.CacheRebuilds
c.Mu.Unlock()
}
s.listNodesPerNetMu.Unlock()
m.ListNodesCacheHits.Set(float64(totalHits))
m.ListNodesCacheWaits.Set(float64(totalWaits))
m.ListNodesCacheRebuilds.Set(float64(totalRebuilds))
}