Skip to content

Commit

Permalink
tetragon: Add missed stats to kprobemetrics package
Browse files Browse the repository at this point in the history
Add tetragon_missed_probes_total metric to kprobemetrics package and
logic to store and collect missed stats.

The missed stats are supported for kprobes and stored per function
and policy name, like for generic kprobes:

  tetragon_missed_probes_total{attach="__x64_sys_close",policy="syswritefollowfdpsswd"} 453
  tetragon_missed_probes_total{attach="__x64_sys_write",policy="syswritefollowfdpsswd"} 455
  tetragon_missed_probes_total{attach="fd_install",policy="syswritefollowfdpsswd"} 451

and multi kprobes:

  tetragon_missed_probes_total{attach="kprobe_multi (3 functions)",policy="syswritefollowfdpsswd"} 41

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
  • Loading branch information
olsajiri committed Apr 28, 2024
1 parent 9098f1e commit 17d8993
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 0 deletions.
9 changes: 9 additions & 0 deletions docs/content/en/docs/reference/metrics.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 87 additions & 0 deletions pkg/metrics/kprobemetrics/collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Tetragon

package kprobemetrics

import (
"github.com/cilium/ebpf/link"
"github.com/cilium/tetragon/pkg/bpf"
"github.com/cilium/tetragon/pkg/sensors"
"github.com/cilium/tetragon/pkg/sensors/base"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sys/unix"
)

// bpfCollector implements prometheus.Collector. It collects metrics directly from BPF maps.
type bpfCollector struct{}

func NewBPFCollector() prometheus.Collector {
return &bpfCollector{}
}

func (c *bpfCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- MissedProbes.Desc()
}

func (c *bpfCollector) Collect(ch chan<- prometheus.Metric) {
allPrograms := sensors.AllPrograms()
for _, prog := range allPrograms {

if prog.Link == nil {
continue
}

info, err := prog.Link.Info()
if err != nil {
continue
}

missed := uint64(0)

switch info.Type {
case link.PerfEventType:
if bpf.HasMissedStatsPerfEvent() {
pevent := info.PerfEvent()
switch pevent.Type {
case unix.BPF_PERF_EVENT_KPROBE, unix.BPF_PERF_EVENT_KRETPROBE:
kprobe := pevent.Kprobe()
missed, _ = kprobe.Missed()
}
} else {
missed = base.GetKprobeMissed(prog.Link)

}
case link.KprobeMultiType:
if bpf.HasMissedStatsKprobeMulti() {
kmulti := info.KprobeMulti()
missed, _ = kmulti.Missed()
} else {
// warn
}
default:
}

ch <- MissedProbes.MustMetric(float64(missed), prog.Policy, prog.Attach)
}
}

// bpfZeroCollector implements prometheus.Collector. It collects "zero" metrics.
// It's intended to be used when BPF metrics are not collected, but we still want
// Prometheus metrics to be exposed.
type bpfZeroCollector struct {
bpfCollector
}

func NewBPFZeroCollector() prometheus.Collector {
return &bpfZeroCollector{
bpfCollector: bpfCollector{},
}
}

func (c *bpfZeroCollector) Describe(ch chan<- *prometheus.Desc) {
c.bpfCollector.Describe(ch)
}

func (c *bpfZeroCollector) Collect(ch chan<- prometheus.Metric) {
ch <- MissedProbes.MustMetric(0, "policy", "attach")
}
18 changes: 18 additions & 0 deletions pkg/metrics/kprobemetrics/missed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Tetragon

package kprobemetrics

import (
"github.com/cilium/tetragon/pkg/metrics"
"github.com/cilium/tetragon/pkg/metrics/consts"
"github.com/prometheus/client_golang/prometheus"
)

var (
MissedProbes = metrics.NewBPFCounter(prometheus.NewDesc(
prometheus.BuildFQName(consts.MetricsNamespace, "", "missed_probes_total"),
"The total number of Tetragon probe missed per program.",
[]string{"policy", "attach"}, nil,
))
)
2 changes: 2 additions & 0 deletions pkg/metrics/metricsconfig/initmetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func initAllHealthMetrics(registry *prometheus.Registry) {
// register custom collectors
registry.MustRegister(observer.NewBPFCollector())
registry.MustRegister(eventmetrics.NewBPFCollector())
registry.MustRegister(kprobemetrics.NewBPFCollector())
}

func InitHealthMetricsForDocs(registry *prometheus.Registry) {
Expand All @@ -70,6 +71,7 @@ func InitHealthMetricsForDocs(registry *prometheus.Registry) {
// register custom zero collectors
registry.MustRegister(observer.NewBPFZeroCollector())
registry.MustRegister(eventmetrics.NewBPFZeroCollector())
registry.MustRegister(kprobemetrics.NewBPFZeroCollector())
}

func initResourcesMetrics(registry *prometheus.Registry) {
Expand Down

0 comments on commit 17d8993

Please sign in to comment.