Skip to content

Commit

Permalink
WIP docs for bpf metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
lambdanis committed Feb 26, 2024
1 parent c725b93 commit f153d38
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 12 deletions.
2 changes: 1 addition & 1 deletion cmd/tetra/metrics/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ func New() *cobra.Command {
}

func initMetrics(_ string, reg *prometheus.Registry, _ *slog.Logger) error {
metricsconfig.InitAllMetrics(reg)
metricsconfig.InitAllMetricsForDocs(reg)
return nil
}
30 changes: 29 additions & 1 deletion pkg/metrics/bpfmetric.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

package metrics

import "github.com/prometheus/client_golang/prometheus"
import (
"github.com/prometheus/client_golang/prometheus"
)

// BPFMetric represents a metric read directly from a BPF map.
// It's intended to be used in custom collectors. The interface doesn't provide
Expand All @@ -16,20 +18,46 @@ type BPFMetric interface {

type bpfCounter struct {
desc *prometheus.Desc
prometheus.CounterOpts
VariableLabels []string
}

func NewBPFCounter(desc *prometheus.Desc) BPFMetric {
return &bpfCounter{desc: desc}
}

func NewBPFCounterFromOpts(opts prometheus.CounterOpts, labelNames []string) *bpfCounter {

Check warning on line 29 in pkg/metrics/bpfmetric.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unexported-return: exported func NewBPFCounterFromOpts returns unexported type *metrics.bpfCounter, which can be annoying to use (revive)
return &bpfCounter{
CounterOpts: opts,
VariableLabels: labelNames,
}
}

func (c *bpfCounter) Desc() *prometheus.Desc {
if c.desc == nil {
c.desc = prometheus.NewDesc(
prometheus.BuildFQName(c.Namespace, c.Subsystem, c.Name),
c.Help,
c.VariableLabels,
c.ConstLabels,
)
}
return c.desc
}

func (c *bpfCounter) MustMetric(value float64, labelValues ...string) prometheus.Metric {
return prometheus.MustNewConstMetric(c.desc, prometheus.CounterValue, value, labelValues...)
}

func (c *bpfCounter) ToProm() *prometheus.CounterVec {
return prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: c.Namespace,
Name: c.Name,
Help: c.Help,
ConstLabels: c.ConstLabels,
}, c.VariableLabels)
}

type bpfGauge struct {
desc *prometheus.Desc
}
Expand Down
8 changes: 8 additions & 0 deletions pkg/metrics/consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@ package consts
const MetricsNamespace = "tetragon"

var KnownMetricLabelFilters = []string{"namespace", "workload", "pod", "binary"}

var (
EmptyPolicyHookLabels = []string{"", ""}
EmptyProcessLabels = []string{"", "", "", ""}

ExamplePolicyHookLabels = []string{"example-tracingpolicy", "example-kprobe"}
ExampleProcessLabels = []string{"example-namespace", "example-workload", "example-pod", "example-binary"}
)
50 changes: 40 additions & 10 deletions pkg/metrics/eventmetrics/eventmetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
package eventmetrics

import (
"fmt"
"slices"

"github.com/cilium/tetragon/api/v1/tetragon"
"github.com/cilium/tetragon/api/v1/tetragon/codegen/helpers"
"github.com/cilium/tetragon/pkg/api/ops"
"github.com/cilium/tetragon/pkg/api/processapi"
"github.com/cilium/tetragon/pkg/filters"
"github.com/cilium/tetragon/pkg/logger"
Expand All @@ -26,11 +30,17 @@ var (
Help: "The total number of Tetragon events",
ConstLabels: nil,
}, []string{"type"})
MissedEvents = metrics.NewBPFCounter(prometheus.NewDesc(
prometheus.BuildFQName(consts.MetricsNamespace, "", "missed_events_total"),
"The total number of Tetragon events per type that are failed to sent from the kernel.",
[]string{"msg_op"}, nil,
))
// MissedEvents = metrics.NewBPFCounter(prometheus.NewDesc(
// prometheus.BuildFQName(consts.MetricsNamespace, "", "missed_events_total"),
// "The total number of Tetragon events per type that are failed to sent from the kernel.",
// []string{"msg_op"}, nil,
// ))
MissedEvents = metrics.NewBPFCounterFromOpts(prometheus.CounterOpts{
Namespace: consts.MetricsNamespace,
Name: "flagsmissed_events_total_total",
Help: "The total number of Tetragon events per type that are failed to sent from the kernel.",
ConstLabels: nil,
}, []string{"msg_op"})
FlagCount = prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: consts.MetricsNamespace,
Name: "flags_total",
Expand Down Expand Up @@ -63,11 +73,31 @@ func InitMetrics(registry *prometheus.Registry) {
registerMetrics(registry)

// Initialize metrics with labels
// TODO:
// events_total: list all possible event types, add example process metadata for docs
// missed_events_total: list all reasonable opcodes for docs
// flags_total: list all possible flags
// policy_events_total: add example policy and hook for docs
for ev := range tetragon.EventType_name {
if tetragon.EventType(ev) != tetragon.EventType_UNDEF && tetragon.EventType(ev) != tetragon.EventType_TEST {
EventsProcessed.WithLabelValues(slices.Concat([]string{tetragon.EventType(ev).String()}, consts.EmptyProcessLabels)...).Add(0)
}
}
for _, v := range exec.FlagStrings {
FlagCount.WithLabelValues(v).Add(0)
}
policyStats.WithLabelValues(slices.Concat(consts.EmptyPolicyHookLabels, consts.EmptyProcessLabels)...).Add(0)
}

func InitMetricsForDocs(registry *prometheus.Registry) {
InitMetrics(registry)
for ev := range tetragon.EventType_name {
if tetragon.EventType(ev) != tetragon.EventType_UNDEF && tetragon.EventType(ev) != tetragon.EventType_TEST {
EventsProcessed.WithLabelValues(slices.Concat([]string{tetragon.EventType(ev).String()}, consts.ExampleProcessLabels)...).Add(0)
}
}
registry.MustRegister(MissedEvents.ToProm())
for opcode := range ops.OpCodeStrings {
if opcode != ops.MsgOpUndef && opcode != ops.MsgOpTest {
MissedEvents.ToProm().WithLabelValues(fmt.Sprint(int32(opcode))).Add(0)
}
}
policyStats.WithLabelValues(slices.Concat(consts.ExamplePolicyHookLabels, consts.ExampleProcessLabels)...).Add(0)
}

func GetProcessInfo(process *tetragon.Process) (binary, pod, workload, namespace string) {
Expand Down
33 changes: 33 additions & 0 deletions pkg/metrics/metricsconfig/initmetrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,36 @@ func InitAllMetrics(registry *prometheus.Registry) {
registry.MustRegister(grpcmetrics.NewServerMetrics())
version.InitMetrics(registry)
}

func InitAllMetricsForDocs(registry *prometheus.Registry) {
errormetrics.InitMetrics(registry)
eventcachemetrics.InitMetrics(registry)
eventmetrics.InitMetricsForDocs(registry)
kprobemetrics.InitMetrics(registry)
mapmetrics.InitMetrics(registry)
opcodemetrics.InitMetrics(registry)
policyfiltermetrics.InitMetrics(registry)
processexecmetrics.InitMetrics(registry)
ringbufmetrics.InitMetrics(registry)
ringbufqueuemetrics.InitMetrics(registry)
syscallmetrics.InitMetrics(registry)
watchermetrics.InitMetrics(registry)
observer.InitMetrics(registry)
tracing.InitMetrics(registry)
ratelimitmetrics.InitMetrics(registry)
policystatemetrics.InitMetrics(registry)

// register BPF collectors
registry.MustRegister(mapmetrics.NewBPFCollector(
eventcache.NewBPFCollector(),
observer.NewBPFCollector(),
process.NewBPFCollector(),
))
// registry.MustRegister(eventmetrics.NewBPFCollector())

// register common third-party collectors
registry.MustRegister(collectors.NewGoCollector())
registry.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}))
registry.MustRegister(grpcmetrics.NewServerMetrics())
version.InitMetrics(registry)
}

0 comments on commit f153d38

Please sign in to comment.