in_ebpf: Generate mostly monotonic event id for increasing traceability - #12002
Conversation
📝 WalkthroughWalkthroughAdds a new eBPF header defining a per-CPU sequence counter map and ChangesEvent ID generation across eBPF trace programs
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
dc22be7 to
e99db64
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e99db64db4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); | ||
| __type(key, __u32); | ||
| __type(value, __u64); | ||
| __uint(max_entries, 1); | ||
| } seq_counter SEC(".maps"); |
There was a problem hiding this comment.
Share event counters across trace objects
When the Trace option is set multiple times (plugins/in_ebpf/in_ebpf.c:263-265), each selected trace is compiled and loaded as its own BPF object, so defining seq_counter in this included header creates a separate counter map for every trace. That means the first event on CPU N from exec, tcp, dns, etc. all receive the same event_id (N << 48), so IDs collide in the combined event stream and cannot reliably trace event order across enabled traces; use a shared/pinned counter or include a trace/object component in the ID.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🧹 Nitpick comments (2)
plugins/in_ebpf/traces/includes/common/event_id.bpf.h (2)
13-25: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueCounter isn't masked before packing into the low 48 bits.
*counteris a free-running__u64that is OR'd directly withcpu_id << 48without masking to 48 bits first. If the per-CPU counter ever exceeds 2^48-1, it will bleed into the CPU-ID bits and corrupt/collide generated IDs. Given the astronomical threshold (~2.8×10^14 events per CPU), this is a very low-probability, long-horizon issue, but masking is trivial to add defensively.🔧 Proposed fix
if (counter) { /* ID is CPU shifted left by 48 bits, OR'd with per-CPU counter */ - *event_id = ((__u64)bpf_get_smp_processor_id() << 48) | (*counter); + *event_id = ((__u64)bpf_get_smp_processor_id() << 48) | (*counter & 0xFFFFFFFFFFFFULL); (*counter)++; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/in_ebpf/traces/includes/common/event_id.bpf.h` around lines 13 - 25, The event ID packing in generate_event_id is combining the CPU ID and the per-CPU sequence counter without constraining the counter to the low 48 bits. Update the generate_event_id logic in event_id.bpf.h so the value read from seq_counter is masked before OR-ing it with bpf_get_smp_processor_id(), keeping the CPU-ID bits in the upper 16 bits and preventing counter overflow from corrupting IDs.
22-24: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low valueFallback event_id of 0 can collide with a legitimately generated ID.
When
bpf_map_lookup_elemfails,event_idis set to0, which is indistinguishable from the actual first generated ID on CPU 0 (0 << 48 | 0). Consider using a distinct sentinel (e.g., all-ones) if consumers need to detect the lookup-failure case.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/in_ebpf/traces/includes/common/event_id.bpf.h` around lines 22 - 24, The fallback path in event_id handling uses a zero value that can be mistaken for a real generated ID; update the lookup-failure branch in event_id.bpf.h so the event_id set by the helper used for bpf_map_lookup_elem failures is a distinct sentinel instead of 0, and make sure any code that reads event_id can recognize that failure state consistently. Use the existing event_id generation/lookup logic in the event_id helper to keep the change localized and avoid colliding with valid IDs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@plugins/in_ebpf/traces/includes/common/event_id.bpf.h`:
- Around line 13-25: The event ID packing in generate_event_id is combining the
CPU ID and the per-CPU sequence counter without constraining the counter to the
low 48 bits. Update the generate_event_id logic in event_id.bpf.h so the value
read from seq_counter is masked before OR-ing it with
bpf_get_smp_processor_id(), keeping the CPU-ID bits in the upper 16 bits and
preventing counter overflow from corrupting IDs.
- Around line 22-24: The fallback path in event_id handling uses a zero value
that can be mistaken for a real generated ID; update the lookup-failure branch
in event_id.bpf.h so the event_id set by the helper used for bpf_map_lookup_elem
failures is a distinct sentinel instead of 0, and make sure any code that reads
event_id can recognize that failure state consistently. Use the existing
event_id generation/lookup logic in the event_id helper to keep the change
localized and avoid colliding with valid IDs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d7da9461-435d-4602-a859-efef2072f66b
📒 Files selected for processing (12)
plugins/in_ebpf/traces/bind/bpf.cplugins/in_ebpf/traces/dns/bpf.cplugins/in_ebpf/traces/exec/bpf.cplugins/in_ebpf/traces/includes/common/encoder.hplugins/in_ebpf/traces/includes/common/event_id.bpf.hplugins/in_ebpf/traces/includes/common/events.hplugins/in_ebpf/traces/malloc/bpf.c.inplugins/in_ebpf/traces/openssl/bpf.c.inplugins/in_ebpf/traces/sched/bpf.cplugins/in_ebpf/traces/signal/bpf.cplugins/in_ebpf/traces/tcp/bpf.cplugins/in_ebpf/traces/vfs/bpf.c
This is because without IDs per CPU, it's really hard to trace the event sequence.
After adding event_id per CPU, it's easier to trace the sequence of events.
Enter
[N/A]in the box, if an item is not applicable to your change.Testing
Before we can approve your change; please submit the following in a comment:
If this is a change to packaging of containers or native binaries then please confirm it works for all targets.
ok-package-testlabel to test for all targets (requires maintainer to do).Documentation
Backporting
Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.
Summary by CodeRabbit
New Features
Bug Fixes