I think I may have found an off-by-one error in the various histogram macros provided by maps.bpf.h - the tl;dr is that when I record a value in an exp2 histogram, I see that value reflected in the bucket below or equal to that value, rather than the first bucket above to that value.
For example, let's say I have buckets for 1, 2, 4, 8, ..., 1024, and I record the value 268. I would expect the buckets corresponding to le="5.12e-07" and le="1.024e-06" to have their values incremented by one - but I am also seeing the bucket for le="2.56e-07" get incremented.
Minimal Example
Here is a fairly minimal example that demonstrates this by just inserting the values 1-8 into an exp2 histogram (I used tp/sched/sched_process_exec as a proxy for an event that will happen almost immediately upon startup - my BPF knowledge is mostly limited to bpftrace and I didn't see an analogue to its BEGIN block that I could use):
...and the output of doing a curl -s http://localhost:9435/metrics | grep ebpf_exporter_poc_values_bucket against sudo ./ebpf_exporter --config.dir=examples --config.names=off_by_one:
I think what's happening here is that ebpf_exporter is using log2l to determine the bucket index, and since it's performing integer arithmetic, log2l is discarding the fractional part of the result toward zero, so log(3) / log(2) = 1.5849625007211563 ends up as 1, but it should be 2.
Hello!
I think I may have found an off-by-one error in the various histogram macros provided by
maps.bpf.h
- the tl;dr is that when I record a value in anexp2
histogram, I see that value reflected in the bucket below or equal to that value, rather than the first bucket above to that value.For example, let's say I have buckets for 1, 2, 4, 8, ..., 1024, and I record the value 268. I would expect the buckets corresponding to
le="5.12e-07"
andle="1.024e-06"
to have their values incremented by one - but I am also seeing the bucket forle="2.56e-07"
get incremented.Minimal Example
Here is a fairly minimal example that demonstrates this by just inserting the values 1-8 into an
exp2
histogram (I usedtp/sched/sched_process_exec
as a proxy for an event that will happen almost immediately upon startup - my BPF knowledge is mostly limited tobpftrace
and I didn't see an analogue to itsBEGIN
block that I could use):...and the output of doing a
curl -s http://localhost:9435/metrics | grep ebpf_exporter_poc_values_bucket
againstsudo ./ebpf_exporter --config.dir=examples --config.names=off_by_one
:By contrast, here's a Go program that creates a Prometheus histogram and observes values 1-8:
...and the resulting output:
Suspected Cause
I think what's happening here is that
ebpf_exporter
is usinglog2l
to determine the bucket index, and since it's performing integer arithmetic,log2l
is discarding the fractional part of the result toward zero, solog(3) / log(2) = 1.5849625007211563
ends up as1
, but it should be2
.