Skip to content

Commit 52143b0

Browse files
authored
Fix name generation for BPF metrics (#1552)
1 parent 9976a4d commit 52143b0

File tree

1 file changed

+51
-35
lines changed

1 file changed

+51
-35
lines changed

pkg/export/prom/prom_bpf.go

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -115,42 +115,49 @@ func (bc *BPFCollector) Collect(ch chan<- prometheus.Metric) {
115115
func (bc *BPFCollector) collectProbesMetrics(ch chan<- prometheus.Metric) {
116116
bc.enableBPFStatsRuntime()
117117

118-
// Iterate over all eBPF programs
119-
ids, err := ebpf.ProgramGetNextID(0)
120-
if err != nil {
121-
bc.log.Error("failed to get first program ID", "ID", ids, "error", err)
122-
}
118+
for id := ebpf.ProgramID(0); ; {
119+
nextID, err := ebpf.ProgramGetNextID(id)
120+
if err != nil {
121+
break
122+
}
123+
id = nextID
123124

124-
for ids != 0 {
125-
// Get the program from the ID
126-
program, err := ebpf.NewProgramFromID(ids)
125+
program, err := ebpf.NewProgramFromID(id)
127126
if err != nil {
128-
bc.log.Error("failed to load program", "ID", ids, "error", err)
127+
bc.log.Error("failed to load program", "ID", id, "error", err)
129128
continue
130129
}
131130
defer program.Close()
132131

133-
// Get program info
134132
info, err := program.Info()
135133
if err != nil {
136-
bc.log.Error("failed to get program info", "ID", ids, "error", err)
134+
bc.log.Error("failed to get program info", "ID", id, "error", err)
137135
continue
138136
}
139137

138+
switch info.Type {
139+
case ebpf.Kprobe, ebpf.SocketFilter, ebpf.SchedCLS, ebpf.SkMsg, ebpf.SockOps:
140+
// Supported program types
141+
default:
142+
continue // Skip unsupported program types
143+
}
144+
145+
name := getFuncName(info, id, bc.log)
146+
140147
runtime, _ := info.Runtime()
141148
runCount, _ := info.RunCount()
142-
idStr := strconv.FormatUint(uint64(ids), 10)
149+
idStr := strconv.FormatUint(uint64(id), 10)
143150

144151
// Get the previous stats
145-
probe, ok := bc.progs[ids]
152+
probe, ok := bc.progs[id]
146153
if !ok {
147154
probe = &BPFProgram{
148155
runTime: runtime,
149156
runCount: runCount,
150157
prevRunTime: 0,
151158
prevRunCount: 0,
152159
}
153-
bc.progs[ids] = probe
160+
bc.progs[id] = probe
154161
} else {
155162
probe.prevRunTime = probe.runTime
156163
probe.prevRunCount = probe.runCount
@@ -167,39 +174,52 @@ func (bc *BPFCollector) collectProbesMetrics(ch chan<- prometheus.Metric) {
167174
probe.buckets,
168175
idStr,
169176
info.Type.String(),
170-
info.Name,
177+
name,
171178
)
172-
173-
// Get the next program ID
174-
ids, _ = ebpf.ProgramGetNextID(ids)
175179
}
176180
}
177181

178-
func (bc *BPFCollector) collectMapMetrics(ch chan<- prometheus.Metric) {
179-
// Iterate over all eBPF maps
180-
ids, err := ebpf.MapGetNextID(0)
182+
func getFuncName(info *ebpf.ProgramInfo, id ebpf.ProgramID, log *slog.Logger) string {
183+
funcInfos, err := info.FuncInfos()
181184
if err != nil {
182-
bc.log.Error("failed to get first map ID", "ID", ids, "error", err)
185+
log.Error("failed to get program func infos", "ID", id, "error", err)
186+
return info.Name
183187
}
184188

185-
for ids != 0 {
186-
// Get the map from the ID
187-
m, err := ebpf.NewMapFromID(ids)
189+
for _, funcOffset := range funcInfos {
190+
if f := funcOffset.Func; f != nil {
191+
return f.Name
192+
}
193+
}
194+
return info.Name
195+
}
196+
197+
func (bc *BPFCollector) collectMapMetrics(ch chan<- prometheus.Metric) {
198+
for id := ebpf.MapID(0); ; {
199+
nextID, err := ebpf.MapGetNextID(id)
188200
if err != nil {
189-
bc.log.Error("failed to load map", "ID", ids, "error", err)
201+
break
202+
}
203+
id = nextID
204+
205+
m, err := ebpf.NewMapFromID(id)
206+
if err != nil {
207+
bc.log.Error("failed to load map", "ID", id, "error", err)
190208
continue
191209
}
192210
defer m.Close()
193211

194-
// Get map info
195212
info, err := m.Info()
196213
if err != nil {
197-
bc.log.Error("failed to get map info", "ID", ids, "error", err)
214+
bc.log.Error("failed to get map info", "ID", id, "error", err)
215+
continue
216+
}
217+
218+
// Only collect maps that are LRUHash
219+
if info.Type != ebpf.LRUHash {
198220
continue
199221
}
200222

201-
// This snippet is copied from digitalocean-labs/ebpf_exporter
202-
// https://github.com/digitalocean-labs/ebpf_exporter/blob/main/collectors/map.go
203223
var count uint64
204224
throwawayKey := discardEncoding{}
205225
throwawayValues := make(sliceDiscardEncoding, 0)
@@ -208,20 +228,16 @@ func (bc *BPFCollector) collectMapMetrics(ch chan<- prometheus.Metric) {
208228
count++
209229
}
210230
if err := iter.Err(); err == nil {
211-
// Create the map metric
212231
ch <- prometheus.MustNewConstMetric(
213232
bc.mapSizeDesc,
214233
prometheus.CounterValue,
215234
float64(count),
216-
strconv.FormatUint(uint64(ids), 10),
235+
strconv.FormatUint(uint64(id), 10),
217236
info.Name,
218237
info.Type.String(),
219238
strconv.FormatUint(uint64(info.MaxEntries), 10),
220239
)
221240
}
222-
223-
// Get the next map ID
224-
ids, _ = ebpf.MapGetNextID(ids)
225241
}
226242
}
227243

0 commit comments

Comments
 (0)