From 4a92d64a18179ab36174806dd85c345987fcd071 Mon Sep 17 00:00:00 2001
From: Mahe Tardy <mahe.tardy@gmail.com>
Date: Tue, 8 Oct 2024 17:13:57 +0200
Subject: [PATCH] pkg/metrics: add metrics for policy kernel memory use

Similarly to TracingPolicy state, you can retrieve this information
through the gRPC API by listing the policies or using the metrics
interface.

Signed-off-by: Mahe Tardy <mahe.tardy@gmail.com>
---
 docs/content/en/docs/reference/metrics.md       | 8 ++++++++
 pkg/metrics/policymetrics/policymetrics.go      | 9 +++++++++
 pkg/metrics/policymetrics/policymetrics_test.go | 5 ++++-
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/docs/content/en/docs/reference/metrics.md b/docs/content/en/docs/reference/metrics.md
index bec127bc64b..0314a205809 100644
--- a/docs/content/en/docs/reference/metrics.md
+++ b/docs/content/en/docs/reference/metrics.md
@@ -287,6 +287,14 @@ Process Loader event statistics. For internal use only.
 | ----- | ------ |
 | `count` | `LoaderReceived, LoaderResolvedImm, LoaderResolvedRetry` |
 
+### `tetragon_tracingpolicy_kernel_memory_bytes`
+
+The amount of kernel memory in bytes used by policy's sensors non-shared BPF maps (memlock).
+
+| label | values |
+| ----- | ------ |
+| `policy` | `example-policy` |
+
 ### `tetragon_tracingpolicy_loaded`
 
 The number of loaded tracing policy by state.
diff --git a/pkg/metrics/policymetrics/policymetrics.go b/pkg/metrics/policymetrics/policymetrics.go
index 961c3ca22b7..378c357bff0 100644
--- a/pkg/metrics/policymetrics/policymetrics.go
+++ b/pkg/metrics/policymetrics/policymetrics.go
@@ -32,12 +32,19 @@ var policyState = metrics.MustNewCustomGauge(metrics.NewOpts(
 	nil, []metrics.ConstrainedLabel{stateLabel}, nil,
 ))
 
+var policyKernelMemory = metrics.MustNewCustomGauge(metrics.NewOpts(
+	consts.MetricsNamespace, "", "tracingpolicy_kernel_memory_bytes",
+	"The amount of kernel memory in bytes used by policy's sensors non-shared BPF maps (memlock).",
+	nil, nil, []metrics.UnconstrainedLabel{{Name: "policy", ExampleValue: "example-policy"}},
+))
+
 // This metric collector converts the output of ListTracingPolicies into a few
 // gauges metrics on collection. Thus, it needs a sensor manager to query.
 func NewPolicyCollector() metrics.CollectorWithInit {
 	return metrics.NewCustomCollector(
 		metrics.CustomMetrics{
 			policyState,
+			policyKernelMemory,
 		},
 		collect,
 		collectForDocs,
@@ -63,6 +70,7 @@ func collect(ch chan<- prometheus.Metric) {
 	for _, policy := range list.Policies {
 		state := policy.State
 		counters[state]++
+		ch <- policyKernelMemory.MustMetric(float64(policy.KernelMemoryBytes), policy.Name)
 	}
 
 	ch <- policyState.MustMetric(
@@ -87,4 +95,5 @@ func collectForDocs(ch chan<- prometheus.Metric) {
 	for _, state := range stateLabel.Values {
 		ch <- policyState.MustMetric(0, state)
 	}
+	ch <- policyKernelMemory.MustMetric(0, "example-policy")
 }
diff --git a/pkg/metrics/policymetrics/policymetrics_test.go b/pkg/metrics/policymetrics/policymetrics_test.go
index f70716d74b2..5c3635e5cb7 100644
--- a/pkg/metrics/policymetrics/policymetrics_test.go
+++ b/pkg/metrics/policymetrics/policymetrics_test.go
@@ -21,7 +21,10 @@ import (
 
 func Test_policyStatusCollector_Collect(t *testing.T) {
 	expectedMetrics := func(disabled, enabled, err, load_error int) io.Reader {
-		return strings.NewReader(fmt.Sprintf(`# HELP tetragon_tracingpolicy_loaded The number of loaded tracing policy by state.
+		return strings.NewReader(fmt.Sprintf(`# HELP tetragon_tracingpolicy_kernel_memory_bytes The amount of kernel memory in bytes used by policy's sensors non-shared BPF maps (memlock).
+# TYPE tetragon_tracingpolicy_kernel_memory_bytes gauge
+tetragon_tracingpolicy_kernel_memory_bytes{policy="pizza"} 0
+# HELP tetragon_tracingpolicy_loaded The number of loaded tracing policy by state.
 # TYPE tetragon_tracingpolicy_loaded gauge
 tetragon_tracingpolicy_loaded{state="disabled"} %d
 tetragon_tracingpolicy_loaded{state="enabled"} %d