Skip to content

Commit 6f0c71e

Browse files
authored
Merge pull request #297 from bobrik/ivan/otel
Add support for opentelemetry tracing
2 parents 4c0fd8e + 3341317 commit 6f0c71e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2565
-68
lines changed

.github/workflows/ci.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,36 @@ jobs:
386386
- name: Build example bpf probes
387387
run: make -j $(nproc) -C examples build
388388

389+
build-tracing-demos-x86_64:
390+
name: Build tracing demos (x86_64)
391+
runs-on: ubuntu-22.04
392+
steps:
393+
- uses: actions/checkout@v4
394+
395+
- uses: actions/setup-go@v5
396+
with:
397+
go-version: ^1.22
398+
399+
- name: Build
400+
run: make -j $(nproc) tracing-demos
401+
402+
- name: Extract tracing-demos.x86_64.tar.gz
403+
run: |
404+
tar -cvzf tracing-demos.x86_64.tar.gz tracing/demos/*/demo
405+
406+
- name: Upload tracing-demos.x86_64.tar.gz
407+
uses: actions/upload-artifact@v3
408+
with:
409+
name: tracing-demos.x86_64.tar.gz
410+
path: tracing-demos.x86_64.tar.gz
411+
if-no-files-found: error
412+
389413
check-configs-x86_64:
390414
name: Check examples
391415
runs-on: ubuntu-22.04
392416
needs:
393417
- build-ebpf-exporter-docker-x86_64
418+
- build-tracing-demos-x86_64
394419
steps:
395420
- uses: actions/checkout@v4
396421

@@ -402,6 +427,14 @@ jobs:
402427
- name: Extract ebpf_exporter_with_examples.x86_64.tar.gz
403428
run: tar --strip-components 1 -xzvf ebpf_exporter_with_examples.x86_64.tar.gz
404429

430+
- name: Download tracing-demos.x86_64.tar.gz
431+
uses: actions/download-artifact@v3
432+
with:
433+
name: tracing-demos.x86_64.tar.gz
434+
435+
- name: Extract tracing-demos.x86_64.tar.gz
436+
run: tar -xzvf tracing-demos.x86_64.tar.gz
437+
405438
- name: Run configuration check
406439
run: make config-check
407440

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
/ebpf_exporter
22
/libbpf
3+
4+
.DS_Store

.vscode/config-schema.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ title: ebpf_exporter config schema
22
$schema: https://json-schema.org/draft/2020-12/schema
33
type: object
44
additionalProperties: false
5+
anyOf:
6+
- required:
7+
- metrics
8+
- required:
9+
- tracing
510
properties:
611
metrics:
712
type: object
@@ -66,6 +71,27 @@ properties:
6671
type: number
6772
labels:
6873
$ref: "#/definitions/labels"
74+
tracing:
75+
type: object
76+
additionalProperties: false
77+
properties:
78+
spans:
79+
type: array
80+
items:
81+
type: object
82+
additionalProperties: false
83+
required:
84+
- ringbuf
85+
- labels
86+
properties:
87+
name:
88+
type: string
89+
ringbuf:
90+
type: string
91+
service:
92+
type: string
93+
labels:
94+
$ref: "#/definitions/labels"
6995
kaddrs:
7096
type: array
7197
items:
@@ -97,6 +123,7 @@ definitions:
97123
enum:
98124
- cgroup
99125
- dname
126+
- hex
100127
- ifname
101128
- inet_ip
102129
- kstack

Makefile

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ CLANG_FORMAT_FILES = ${wildcard examples/*.c examples/*.h benchmark/probes/*.c b
3030
CONFIGS_TO_IGNORE_IN_CHECK := cachestat kfree_skb llcstat pci unix-socket-backlog
3131
CONFIGS_TO_CHECK := $(filter-out $(CONFIGS_TO_IGNORE_IN_CHECK), ${patsubst examples/%.yaml, %, ${wildcard examples/*.yaml}})
3232

33-
export CGO_LDFLAGS := -l bpf
33+
CGO_LDFLAGS := -l bpf
3434

3535
include Makefile.libbpf
3636

@@ -55,7 +55,7 @@ clang-format-check:
5555

5656
.PHONY: test
5757
test: $(LIBBPF_DEPS)
58-
go test -ldflags='-extldflags "-static"' $(GO_TEST_ARGS) ./...
58+
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go test -ldflags='-extldflags "-static"' $(GO_TEST_ARGS) ./...
5959

6060
.PHONY: test-privileged
6161
test-privileged:
@@ -78,8 +78,23 @@ build-dynamic:
7878

7979
.PHONY: build-binary
8080
build-binary: $(LIBBPF_DEPS)
81-
go build -o ebpf_exporter -v -ldflags="$(GO_LDFLAGS) $(GO_LDFLAGS_VARS)" ./cmd/ebpf_exporter
81+
CGO_LDFLAGS="$(CGO_LDFLAGS)" CGO_CFLAGS="$(CGO_CFLAGS)" go build -o ebpf_exporter -v -ldflags="$(GO_LDFLAGS) $(GO_LDFLAGS_VARS)" ./cmd/ebpf_exporter
82+
83+
.PHONY: examples
84+
examples:
85+
$(MAKE) -C examples
86+
87+
.PHONY: tracing-demos
88+
tracing-demos:
89+
$(MAKE) -C tracing/demos
8290

8391
.PHONY: syscalls
8492
syscalls:
8593
go run ./scripts/mksyscalls --strace.version v6.4
94+
95+
.PHONY: clean
96+
clean:
97+
rm -rf ebpf_exporter libbpf
98+
$(MAKE) -C tracing/demos clean
99+
$(MAKE) -C examples clean
100+
$(MAKE) -C benchmark clean

Makefile.libbpf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ ifneq ($(BUILD_LIBBPF),0)
88
LIBBPF_DEPS := $(LIBBPF_PATH)
99
LIBBPF_CFLAGS := -I$(LIBBPF_TOP)/libbpf/dest/usr/include
1010
LIBBPF_LDFLAGS := -L$(LIBBPF_TOP)/libbpf/dest/usr/lib
11-
export CGO_LDFLAGS := $(CGO_LDFLAGS) $(LIBBPF_LDFLAGS)
12-
export CGO_CFLAGS := $(LIBBPF_CFLAGS)
11+
CGO_LDFLAGS := $(CGO_LDFLAGS) $(LIBBPF_LDFLAGS)
12+
CGO_CFLAGS := $(LIBBPF_CFLAGS)
1313
endif
1414

1515
.PHONY: clean-libbpf

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# ebpf_exporter
22

3-
Prometheus exporter for custom eBPF metrics.
3+
Prometheus exporter for custom eBPF metrics and OpenTelemetry traces.
4+
5+
* Metrics:
6+
7+
![metrics](./examples/biolatency.png)
8+
9+
* [Traces](./tracing):
10+
11+
![tracing](./tracing/demos/exec/trace.png)
412

513
Motivation of this exporter is to allow you to write eBPF code and export
614
metrics that are not otherwise accessible from the Linux kernel.
@@ -20,6 +28,9 @@ We use libbpf rather than legacy bcc driven code, so it's more like libbpf-tools
2028

2129
* https://github.com/iovisor/bcc/tree/master/libbpf-tools
2230

31+
Producing [OpenTelemetry](https://opentelemetry.io/) compatible traces is also
32+
supported, see [Tracing docs](./tracing/) for more information on that.
33+
2334
## Reading material
2435

2536
* https://www.brendangregg.com/ebpf.html
@@ -377,7 +388,7 @@ ebpf_exporter_bio_latency_seconds_count{device="nvme1n1",operation="write"} 1
377388

378389
You can nicely plot this with Grafana:
379390

380-
![Histogram](examples/bio.write.latency.png)
391+
![Histogram](./examples/biolatency.png)
381392

382393
## Configuration concepts
383394

@@ -585,6 +596,10 @@ could be used after `string` decode, like the following example:
585596
- name: dname
586597
```
587598
599+
### `hex`
600+
601+
Hex decoder turns bytes into their hex representation.
602+
588603
#### `inet_ip`
589604

590605
Network IP decoded can turn byte encoded IPv4 and IPv6 addresses

benchmark/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.DEFAULT_GOAL := build
22

3-
export CGO_LDFLAGS := -l bpf
3+
CGO_LDFLAGS := -l bpf
44

55
include ../Makefile.libbpf
66

cmd/ebpf_exporter/main.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ import (
44
"fmt"
55
"log"
66
"net/http"
7+
"os"
78
"strconv"
89
"strings"
910
"time"
1011

1112
"github.com/aquasecurity/libbpfgo"
1213
"github.com/cloudflare/ebpf_exporter/v2/config"
1314
"github.com/cloudflare/ebpf_exporter/v2/exporter"
15+
"github.com/cloudflare/ebpf_exporter/v2/tracing"
1416
"github.com/coreos/go-systemd/activation"
1517
"github.com/prometheus/client_golang/prometheus"
1618
"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -58,7 +60,16 @@ func main() {
5860
log.Fatalf("Error parsing configs: %v", err)
5961
}
6062

61-
e, err := exporter.New(configs, *btfPath)
63+
if os.Getenv("OTEL_SERVICE_NAME") == "" {
64+
os.Setenv("OTEL_SERVICE_NAME", "ebpf_exporter")
65+
}
66+
67+
processor, err := tracing.NewProcessor()
68+
if err != nil {
69+
log.Fatalf("Error creating tracing processor: %v", err)
70+
}
71+
72+
e, err := exporter.New(configs, tracing.NewProvider(processor), *btfPath)
6273
if err != nil {
6374
log.Fatalf("Error creating exporter: %s", err)
6475
}

config/config.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
type Config struct {
1414
Name string `yaml:"name"`
1515
Metrics Metrics `yaml:"metrics"`
16+
Tracing Tracing `yaml:"tracing"`
1617
Kaddrs []string `yaml:"kaddrs"`
1718
BPFPath string
1819
}
@@ -44,6 +45,19 @@ type Histogram struct {
4445
Labels []Label `yaml:"labels"`
4546
}
4647

48+
// Tracing is a collection of spans attached to a program
49+
type Tracing struct {
50+
Spans []Span `yaml:"spans"`
51+
}
52+
53+
// Span describes how a span is decoded from the kernel
54+
type Span struct {
55+
RingBuf string `yaml:"ringbuf"`
56+
Name string `yaml:"name"`
57+
Service string `yaml:"service"`
58+
Labels []Label `yaml:"labels"`
59+
}
60+
4761
// Label defines how to decode an element from eBPF map key
4862
// with the list of decoders
4963
type Label struct {
@@ -107,8 +121,8 @@ func ParseConfigs(dir string, names []string) ([]Config, error) {
107121
}
108122

109123
func validateConfig(cfg *Config) error {
110-
if cfg.Metrics.Counters == nil && cfg.Metrics.Histograms == nil {
111-
return fmt.Errorf("metrics are not defined for config %q", cfg.Name)
124+
if cfg.Metrics.Counters == nil && cfg.Metrics.Histograms == nil && cfg.Tracing.Spans == nil {
125+
return fmt.Errorf("neither metrics nor tracing are defined for config %q", cfg.Name)
112126
}
113127

114128
for _, counter := range cfg.Metrics.Counters {

decoder/decoder.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func NewSet() (*Set, error) {
4242
decoders: map[string]Decoder{
4343
"cgroup": cgroup,
4444
"dname": &Dname{},
45+
"hex": &Hex{},
4546
"ifname": &IfName{},
4647
"inet_ip": &InetIP{},
4748
"kstack": &KStack{ksym},

0 commit comments

Comments
 (0)