Skip to content

Commit 1d9a9b6

Browse files
author
Mario Macias
authored
NETOBSERV-201: configure LogLevel and Sampling (#16)
* NETOBSERV-201: configure LogLevel and Sampling * updated go mod
1 parent e9b1d44 commit 1d9a9b6

File tree

10 files changed

+46
-14
lines changed

10 files changed

+46
-14
lines changed

bpf/flows.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ struct {
2323
__uint(max_entries, 1 << 24);
2424
} flows SEC(".maps");
2525

26+
// Constant definitions, to be overridden by the invoker
27+
volatile const u32 sampling = 0;
28+
2629
// sets flow fields from IPv4 header information
2730
static inline int fill_iphdr(struct iphdr *ip, void *data_end, struct flow *flow) {
2831
if ((void *)ip + sizeof(*ip) > data_end) {
@@ -72,6 +75,12 @@ static inline int fill_ethhdr(struct ethhdr *eth, void *data_end, struct flow *f
7275

7376
// parses flow information for a given direction (ingress/egress)
7477
static inline int flow_parse(struct __sk_buff *skb, u8 direction) {
78+
79+
// If sampling is defined, will only parse 1 out of "sampling" flows
80+
if (sampling != 0 && (bpf_get_prandom_u32() % sampling) != 0) {
81+
return TC_ACT_OK;
82+
}
83+
7584
void *data = (void *)(long)skb->data;
7685
void *data_end = (void *)(long)skb->data_end;
7786

cmd/netobserv-ebpf-agent.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ func main() {
2121
if err := env.Parse(&config); err != nil {
2222
logrus.WithError(err).Fatal("can't load configuration from environment")
2323
}
24-
if config.Verbose {
25-
logrus.SetLevel(logrus.DebugLevel)
26-
}
24+
setLoggerVerbosity(&config)
2725

2826
logrus.WithField("configuration", fmt.Sprintf("%#v", config)).Debugf("configuration loaded")
2927

@@ -45,3 +43,12 @@ func main() {
4543
logrus.WithError(err).Fatal("can't start netobserv-ebpf-agent")
4644
}
4745
}
46+
47+
func setLoggerVerbosity(cfg *agent.Config) {
48+
lvl, err := logrus.ParseLevel(cfg.LogLevel)
49+
if err != nil {
50+
logrus.WithError(err).Warn("assuming 'info' logger level as default")
51+
lvl = logrus.InfoLevel
52+
}
53+
logrus.SetLevel(lvl)
54+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/sirupsen/logrus v1.8.1
1212
github.com/stretchr/testify v1.7.1
1313
github.com/vishvananda/netlink v1.1.0
14+
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
1415
google.golang.org/grpc v1.45.0
1516
google.golang.org/protobuf v1.28.0
1617
)
@@ -22,7 +23,6 @@ require (
2223
github.com/pmezard/go-difflib v1.0.0 // indirect
2324
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
2425
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect
25-
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
2626
golang.org/x/text v0.3.7 // indirect
2727
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
2828
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac // indirect

pkg/agent/agent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func FlowsAgent(cfg *Config) (*Flows, error) {
4242
}
4343
tracers := map[string]flowTracer{}
4444
for iface := range interfaces {
45-
tracers[iface] = ebpf.NewFlowTracer(iface)
45+
tracers[iface] = ebpf.NewFlowTracer(iface, cfg.Sampling)
4646
}
4747
target := fmt.Sprintf("%s:%d", cfg.TargetHost, cfg.TargetPort)
4848
grpcExporter, err := exporter.StartGRPCProto(target)

pkg/agent/agent_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ func TestFlowsAgent(t *testing.T) {
2828
flowsAgent, err := FlowsAgent(&Config{
2929
TargetHost: "127.0.0.1",
3030
TargetPort: port,
31-
Verbose: true,
3231
CacheMaxFlows: 1,
3332
CacheActiveTimeout: 5 * time.Second,
3433
BuffersLength: 10,

pkg/agent/config.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ type Config struct {
3232
// CacheActiveTimeout specifies the maximum duration in which a flow is kept in the accounting
3333
// cache before being flushed for its later export
3434
CacheActiveTimeout time.Duration `env:"CACHE_ACTIVE_TIMEOUT" envDefault:"5s"`
35-
// Verbose logs mode
36-
Verbose bool `env:"VERBOSE" envDefault:"false"`
35+
// Logger level. From more to less verbose: trace, debug, info, warn, error, fatal, panic.
36+
LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
37+
// Sampling holds the rate at which packets should be sampled and sent to the target collector.
38+
// E.g. if set to 100, one out of 100 packets, on average, will be sent to each target collector.
39+
Sampling uint32 `env:"SAMPLING" envDefault:"0"`
3740
}
3841

3942
func getInterfaces(cfg *Config, interfaces func() ([]net.Interface, error)) (map[string]struct{}, error) {

pkg/ebpf/bpf_bpfeb.o

1.01 KB
Binary file not shown.

pkg/ebpf/bpf_bpfel.o

1.01 KB
Binary file not shown.

pkg/ebpf/tracer.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,24 @@ import (
1515
"github.com/netobserv/netobserv-ebpf-agent/pkg/flow"
1616
"github.com/sirupsen/logrus"
1717
"github.com/vishvananda/netlink"
18+
"golang.org/x/sys/unix"
1819
)
1920

2021
// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile.
2122
//go:generate bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf ../../bpf/flows.c -- -I../../bpf/headers
2223

2324
const (
2425
qdiscType = "clsact"
26+
// constants defined in flows.c as "volatile const"
27+
constSampling = "sampling"
2528
)
2629

2730
var log = logrus.WithField("component", "ebpf.FlowTracer")
2831

2932
// FlowTracer reads and forwards the Flows from the Transmission Control, for a given interface.
3033
type FlowTracer struct {
3134
interfaceName string
35+
sampling uint32
3236
objects bpfObjects
3337
qdisc *netlink.GenericQdisc
3438
egressFilter *netlink.BpfFilter
@@ -37,10 +41,11 @@ type FlowTracer struct {
3741
}
3842

3943
// NewFlowTracer fo a given interface type
40-
func NewFlowTracer(iface string) *FlowTracer {
44+
func NewFlowTracer(iface string, sampling uint32) *FlowTracer {
4145
log.WithField("iface", iface).Debug("Instantiating flow tracer")
4246
return &FlowTracer{
4347
interfaceName: iface,
48+
sampling: sampling,
4449
}
4550
}
4651

@@ -53,9 +58,18 @@ func (m *FlowTracer) Register() error {
5358
if err := rlimit.RemoveMemlock(); err != nil {
5459
return fmt.Errorf("removing mem lock: %w", err)
5560
}
56-
// Load pre-compiled programs and maps into the kernel.
57-
if err := loadBpfObjects(&m.objects, nil); err != nil {
58-
return fmt.Errorf("loading objects: %w", err)
61+
// Load pre-compiled programs and maps into the kernel, and rewrites the configuration
62+
spec, err := loadBpf()
63+
if err != nil {
64+
return fmt.Errorf("loading BPF data: %w", err)
65+
}
66+
if err := spec.RewriteConstants(map[string]interface{}{
67+
constSampling: m.sampling,
68+
}); err != nil {
69+
return fmt.Errorf("rewriting BPF constants definition: %w", err)
70+
}
71+
if err := spec.LoadAndAssign(&m.objects, nil); err != nil {
72+
return fmt.Errorf("loading and assigning BPF objects: %w", err)
5973
}
6074
ipvlan, err := netlink.LinkByName(m.interfaceName)
6175
if err != nil {
@@ -110,7 +124,7 @@ func (m *FlowTracer) Register() error {
110124
LinkIndex: ipvlan.Attrs().Index,
111125
Parent: netlink.HANDLE_MIN_INGRESS,
112126
Handle: netlink.MakeHandle(0, 1),
113-
Protocol: 3,
127+
Protocol: unix.ETH_P_ALL,
114128
Priority: 1,
115129
}
116130
m.ingressFilter = &netlink.BpfFilter{

scripts/generators.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
FROM fedora:35
22

3-
ARG GOVERSION="1.17.8"
3+
ARG GOVERSION="1.17.9"
44
ARG PROTOCVERSION="3.19.4"
55

66
# Installs dependencies that are required to compile eBPF programs

0 commit comments

Comments
 (0)