Skip to content

Commit dc8baec

Browse files
authored
Add docker and containerd meta labels (#3102)
This adds docker and containerd container labels as meta labels so users can relabel them onto samples the same way as it is possible with eg. kubernetes pod labels.
2 parents 2fd5666 + f6bc49a commit dc8baec

File tree

6 files changed

+49
-20
lines changed

6 files changed

+49
-20
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,13 @@ Using relabeling the following labels can be attached to profiles:
301301
* `__meta_kubernetes_node_annotationpresent_*`: Whether the annotation `*` of the node the process is running on is present.
302302
* `__meta_docker_container_id`: The ID of the container the process is running in.
303303
* `__meta_docker_container_name`: The name of the container the process is running in.
304+
* `__meta_docker_container_label_*`: The value of the label `*` of the container the process is running in.
305+
* `__meta_docker_container_labelpresent_*`: Whether the label `*` of the container the process is running in is present.
304306
* `__meta_docker_build_kit_container_id`: The ID of the container the process is running in.
305307
* `__meta_containerd_container_id`: The ID of the container the process is running in.
306308
* `__meta_containerd_container_name`: The name of the container the process is running in.
309+
* `__meta_containerd_container_label_*`: The value of the label `*` of the container the process is running in.
310+
* `__meta_containerd_container_labelpresent_*`: Whether the label `*` of the container the process is running in is present.
307311
* `__meta_containerd_pod_name`: The name of the pod the process is running in.
308312
* `__meta_lxc_container_id`: The ID of the container the process is running in.
309313
* `__meta_cpu`: The CPU the sample was taken on.

reporter/metadata/agent.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package metadata
22

33
import (
4-
"go.opentelemetry.io/ebpf-profiler/libpf"
4+
"context"
5+
56
"github.com/prometheus/prometheus/model/labels"
7+
"go.opentelemetry.io/ebpf-profiler/libpf"
68
)
79

810
type agentMetadataProvider struct {
@@ -13,7 +15,7 @@ func NewAgentMetadataProvider(revision string) MetadataProvider {
1315
return &agentMetadataProvider{revision: revision}
1416
}
1517

16-
func (p *agentMetadataProvider) AddMetadata(_ libpf.PID, lb *labels.Builder) bool {
18+
func (p *agentMetadataProvider) AddMetadata(_ context.Context, _ libpf.PID, lb *labels.Builder) bool {
1719
lb.Set("__meta_agent_revision", p.revision)
1820
return true
1921
}

reporter/metadata/containermetadata.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ var (
9999
type MetadataProvider interface {
100100
// AddMetadata adds metadata to the provided labels.Builder for the given PID.
101101
// It returns whether the metadata can be safely cached.
102-
AddMetadata(pid libpf.PID, lb *labels.Builder) bool
102+
AddMetadata(ctx context.Context, pid libpf.PID, lb *labels.Builder) bool
103103
}
104104

105105
// containerMetadataProvider does the retrieval of container metadata for a particular pid.
@@ -521,7 +521,7 @@ func matchContainerID(containerIDStr string) (string, error) {
521521
}
522522

523523
// AddMetadata adds metadata to the provided labels.Builder for the given PID.
524-
func (p *containerMetadataProvider) AddMetadata(pid libpf.PID, lb *labels.Builder) bool {
524+
func (p *containerMetadataProvider) AddMetadata(ctx context.Context, pid libpf.PID, lb *labels.Builder) bool {
525525
// Fast path, check container metadata has been cached
526526
// For kubernetes pods, the shared informer may have updated
527527
// the container id to container metadata cache, so retrieve the container ID for this pid.
@@ -552,7 +552,7 @@ func (p *containerMetadataProvider) AddMetadata(pid libpf.PID, lb *labels.Builde
552552
// client.
553553
switch {
554554
case isContainerEnvironment(env, envKubernetes) && p.kubeClientSet != nil:
555-
metadata, err := p.getKubernetesPodMetadata(pidContainerID)
555+
metadata, err := p.getKubernetesPodMetadata(ctx, pidContainerID)
556556
if err != nil {
557557
log.Debugf("Failed to get kubernetes pod metadata for container id %v: %v",
558558
pidContainerID, err)
@@ -563,7 +563,7 @@ func (p *containerMetadataProvider) AddMetadata(pid libpf.PID, lb *labels.Builde
563563
}
564564
return true
565565
case isContainerEnvironment(env, envDocker) && p.dockerClient != nil:
566-
metadata, err := p.getDockerContainerMetadata(pidContainerID)
566+
metadata, err := p.getDockerContainerMetadata(ctx, pidContainerID)
567567
if err != nil {
568568
log.Warnf("Failed to get docker container metadata for container id %v: %v",
569569
pidContainerID, err)
@@ -574,7 +574,7 @@ func (p *containerMetadataProvider) AddMetadata(pid libpf.PID, lb *labels.Builde
574574
}
575575
return true
576576
case isContainerEnvironment(env, envContainerd) && p.containerdClient != nil:
577-
metadata, err := p.getContainerdContainerMetadata(pidContainerID)
577+
metadata, err := p.getContainerdContainerMetadata(ctx, pidContainerID)
578578
if err != nil {
579579
log.Debugf("Failed to get containerd container metadata for container id %v: %v",
580580
pidContainerID, err)
@@ -596,12 +596,12 @@ func (p *containerMetadataProvider) AddMetadata(pid libpf.PID, lb *labels.Builde
596596
}
597597
}
598598

599-
func (p *containerMetadataProvider) getKubernetesPodMetadata(pidContainerID string) (
599+
func (p *containerMetadataProvider) getKubernetesPodMetadata(ctx context.Context, pidContainerID string) (
600600
model.LabelSet, error) {
601601
log.Debugf("Get kubernetes pod metadata for container id %v", pidContainerID)
602602

603603
p.kubernetesClientQueryCount.Add(1)
604-
pods, err := p.kubeClientSet.CoreV1().Pods("").List(context.TODO(), v1.ListOptions{
604+
pods, err := p.kubeClientSet.CoreV1().Pods("").List(ctx, v1.ListOptions{
605605
FieldSelector: "spec.nodeName=" + p.nodeName,
606606
})
607607
if err != nil {
@@ -657,12 +657,12 @@ func (p *containerMetadataProvider) getKubernetesPodMetadata(pidContainerID stri
657657
"containerID '%v' in %d pods", pidContainerID, len(pods.Items))
658658
}
659659

660-
func (p *containerMetadataProvider) getDockerContainerMetadata(pidContainerID string) (
660+
func (p *containerMetadataProvider) getDockerContainerMetadata(ctx context.Context, pidContainerID string) (
661661
model.LabelSet, error) {
662662
log.Debugf("Get docker container metadata for container id %v", pidContainerID)
663663

664664
p.dockerClientQueryCount.Add(1)
665-
containers, err := p.dockerClient.ContainerList(context.Background(),
665+
containers, err := p.dockerClient.ContainerList(ctx,
666666
container.ListOptions{})
667667
if err != nil {
668668
return nil, fmt.Errorf("failed to list docker containers, %v", err)
@@ -676,6 +676,13 @@ func (p *containerMetadataProvider) getDockerContainerMetadata(pidContainerID st
676676
"__meta_docker_container_id": lv(containers[i].ID),
677677
"__meta_docker_container_name": lv(containerName),
678678
}
679+
680+
for k, v := range containers[i].Labels {
681+
ln := strutil.SanitizeLabelName(k)
682+
metadata[model.LabelName("__meta_docker_container_label_"+ln)] = lv(v)
683+
metadata[model.LabelName("__meta_docker_container_labelpresent_"+ln)] = presentValue
684+
}
685+
679686
p.containerMetadataCache.Add(pidContainerID, metadata)
680687
return metadata, nil
681688
}
@@ -686,7 +693,7 @@ func (p *containerMetadataProvider) getDockerContainerMetadata(pidContainerID st
686693
pidContainerID)
687694
}
688695

689-
func (p *containerMetadataProvider) getContainerdContainerMetadata(pidContainerID string) (
696+
func (p *containerMetadataProvider) getContainerdContainerMetadata(ctx context.Context, pidContainerID string) (
690697
model.LabelSet, error) {
691698
log.Debugf("Get containerd container metadata for container id %v", pidContainerID)
692699

@@ -701,7 +708,7 @@ func (p *containerMetadataProvider) getContainerdContainerMetadata(pidContainerI
701708
}
702709

703710
p.containerdClientQueryCount.Add(1)
704-
ctx := namespaces.WithNamespace(context.Background(), fields[1])
711+
ctx = namespaces.WithNamespace(ctx, fields[1])
705712
containers, err := p.containerdClient.Containers(ctx)
706713
if err != nil {
707714
return nil,
@@ -718,6 +725,19 @@ func (p *containerMetadataProvider) getContainerdContainerMetadata(pidContainerI
718725
"__meta_containerd_container_name": lv(fields[2]),
719726
"__meta_containerd_pod_name": lv(fields[1]),
720727
}
728+
729+
lbls, err := container.Labels(ctx)
730+
if err != nil {
731+
return nil,
732+
fmt.Errorf("failed to get containerd container labels for container id '%s': %v",
733+
fields[2], err)
734+
}
735+
for k, v := range lbls {
736+
ln := strutil.SanitizeLabelName(k)
737+
metadata[model.LabelName("__meta_containerd_container_label_"+ln)] = lv(v)
738+
metadata[model.LabelName("__meta_containerd_container_labelpresent_"+ln)] = presentValue
739+
}
740+
721741
p.containerMetadataCache.Add(pidContainerID, metadata)
722742
return metadata, nil
723743
}

reporter/metadata/process.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package metadata
33
import (
44
"bufio"
55
"bytes"
6+
"context"
67
"errors"
78
"fmt"
89
"io"
@@ -12,9 +13,9 @@ import (
1213
"strings"
1314

1415
lru "github.com/elastic/go-freelru"
15-
"go.opentelemetry.io/ebpf-profiler/libpf"
1616
"github.com/prometheus/prometheus/model/labels"
1717
log "github.com/sirupsen/logrus"
18+
"go.opentelemetry.io/ebpf-profiler/libpf"
1819
)
1920

2021
var ErrFileParse = errors.New("Error Parsing File")
@@ -167,6 +168,7 @@ func NewMainExecutableMetadataProvider(
167168

168169
// AddMetadata adds metadata labels for the main executable of a process to the given labels.Builder.
169170
func (p *mainExecutableMetadataProvider) AddMetadata(
171+
_ context.Context,
170172
pid libpf.PID,
171173
lb *labels.Builder,
172174
) bool {
@@ -202,7 +204,7 @@ func NewProcessMetadataProvider() MetadataProvider {
202204
}
203205

204206
// AddMetadata adds metadata labels for a process to the given labels.Builder.
205-
func (pmp *processMetadataProvider) AddMetadata(pid libpf.PID, lb *labels.Builder) bool {
207+
func (pmp *processMetadataProvider) AddMetadata(_ context.Context, pid libpf.PID, lb *labels.Builder) bool {
206208
cache := true
207209
lb.Set("__meta_process_pid", strconv.Itoa(int(pid)))
208210

reporter/metadata/system.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package metadata
22

33
import (
4+
"context"
45
"strings"
56
"syscall"
67

7-
"go.opentelemetry.io/ebpf-profiler/libpf"
88
"github.com/prometheus/prometheus/model/labels"
9+
"go.opentelemetry.io/ebpf-profiler/libpf"
910
)
1011

1112
type systemMetadataProvider struct {
@@ -37,7 +38,7 @@ func NewSystemMetadataProvider() (MetadataProvider, error) {
3738
}, nil
3839
}
3940

40-
func (p *systemMetadataProvider) AddMetadata(_ libpf.PID, lb *labels.Builder) bool {
41+
func (p *systemMetadataProvider) AddMetadata(_ context.Context, _ libpf.PID, lb *labels.Builder) bool {
4142
lb.Set("__meta_system_kernel_machine", p.kernelMachine)
4243
lb.Set("__meta_system_kernel_release", p.kernelRelease)
4344
return true

reporter/parca_reporter.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,11 @@ func (r *ParcaReporter) ReportTraceEvent(trace *libpf.Trace,
285285
return nil
286286
}
287287

288-
func (r *ParcaReporter) addMetadataForPID(pid libpf.PID, lb *labels.Builder) bool {
288+
func (r *ParcaReporter) addMetadataForPID(ctx context.Context, pid libpf.PID, lb *labels.Builder) bool {
289289
cache := true
290290

291291
for _, p := range r.metadataProviders {
292-
cacheable := p.AddMetadata(pid, lb)
292+
cacheable := p.AddMetadata(ctx, pid, lb)
293293
cache = cache && cacheable
294294
}
295295

@@ -315,7 +315,7 @@ func (r *ParcaReporter) labelsForTID(tid, pid libpf.PID, comm string, cpu int, e
315315
lb.Set("job", "oomprof")
316316
}
317317

318-
cacheable := r.addMetadataForPID(pid, lb)
318+
cacheable := r.addMetadataForPID(context.TODO(), pid, lb)
319319

320320
keep := relabel.ProcessBuilder(lb, r.relabelConfigs...)
321321

0 commit comments

Comments
 (0)