Skip to content

FIx for BSP benchmark aux counters (exportedSpans/droppedSpans) always reporting zero#8539

Open
EvgeniiR wants to merge 4 commits into
open-telemetry:mainfrom
EvgeniiR:bsp-benchmark-aux-counters
Open

FIx for BSP benchmark aux counters (exportedSpans/droppedSpans) always reporting zero#8539
EvgeniiR wants to merge 4 commits into
open-telemetry:mainfrom
EvgeniiR:bsp-benchmark-aux-counters

Conversation

@EvgeniiR

@EvgeniiR EvgeniiR commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

TLDR

Closes issue #8538 (BatchSpanProcessorDroppedSpansBenchmark, BatchSpanProcessorMultiThreadBenchmark, and BatchSpanProcessorCpuBenchmark were reporting exportedSpans and droppedSpans auxiliary counters as 0)

  • Fixed an issue where exportedSpans / droppedSpans metrics were always reported as 0
  • Switched AuxCounters.Type from OPERATIONS to EVENTS in DroppedSpansBenchmark and MultiThreadBenchmark to fix misleading throughput-normalized counters and make drop rates and totals directly interpretable.
  • Small refactoring of affected benchmark classes (removed duplicated numThreads variable)

BatchSpanProcessorDroppedSpansBenchmark impact

Running BatchSpanProcessorDroppedSpansBenchmark on main produces (measured with
-PjmhIterations=1 -PjmhTime=5; the benchmark default is 20s):

Benchmark                                    Mode   Score
BatchSpanProcessorDroppedSpansBenchmark.export  thrpt  10 054 842 ops/s
  exportedSpans:  ≈ 0 ops/s   ← always zero, bug
  droppedSpans:   ≈ 0 ops/s   ← always zero, bug
  dropRatio:      n/a          ← does not exist on main

With the fix applied (measured with -PjmhIterations=1 -PjmhTime=5):

Benchmark                                    Mode   Score
BatchSpanProcessorDroppedSpansBenchmark.export  thrpt  13 300 880 ops/s
  exportedSpans:  53 300 735   ← total spans exported in iteration (5s)
  droppedSpans:   13 203 785   ← total spans dropped; drop rate ≈ 19.9%
  dropRatio:      0.199        ← per-iteration drop ratio, directly readable

Type.EVENTS aux counters report the total event count for the measurement iteration,
not a per-second rate.

BatchSpanProcessorMultiThreadBenchmark impact

MultiThreadBenchmark shares the same BatchSpanProcessorMetrics helper, so it carried the
same stringKey bug — all counters reported ≈ 0 on main.

Before fix (all thread variants, measured with -PjmhIterations=1 -PjmhTime=5):

export_01Thread  thrpt:  6 804 256 ops/s  exportedSpans: ≈ 0 ops/s  droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_02Thread  thrpt:  7 096 311 ops/s  exportedSpans: ≈ 0 ops/s  droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_05Thread  thrpt: 10 041 481 ops/s  exportedSpans: ≈ 0 ops/s  droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_10Thread  thrpt:  8 087 320 ops/s  exportedSpans: ≈ 0 ops/s  droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_20Thread  thrpt: 11 468 451 ops/s  exportedSpans: ≈ 0 ops/s  droppedSpans: ≈ 0 ops/s   ← always zero, bug

After fix — Type.EVENTS + BenchmarkParams (measured with -PjmhIterations=1 -PjmhTime=5).
With Type.EVENTS, aux counters report absolute totals per iteration rather than a per-second
rate, so dropRatio = droppedSpans / (exportedSpans + droppedSpans) is directly readable:

export_01Thread  thrpt:  7 368 011 ops/s  exportedSpans: 36 276 736 #  droppedSpans:     565 127 #  drop rate:  1.5%
export_02Thread  thrpt:  7 612 288 ops/s  exportedSpans: 37 061 120 #  droppedSpans:   1 001 304 #  drop rate:  2.6%
export_05Thread  thrpt:  9 911 699 ops/s  exportedSpans: 24 016 895 #  droppedSpans:  25 542 165 #  drop rate: 51.5%
export_10Thread  thrpt: 11 255 927 ops/s  exportedSpans: 49 254 910 #  droppedSpans:   7 024 210 #  drop rate: 12.5%
export_20Thread  thrpt: 12 248 437 ops/s  exportedSpans: 15 362 560 #  droppedSpans:  45 891 840 #  drop rate: 74.9%

BatchSpanProcessorCpuBenchmark impact

CpuBenchmark keeps Type.OPERATIONS — each operation submits exactly one span and
LockSupport.parkNanos(100_000) limits throughput to ~10k spans/sec per thread, so per-second
values are readable integers. The stringKey bug caused all counters to report ≈ 0:

Before fix (all thread variants):

export_01Thread  thrpt:   6 360 ops/s  exportedSpans: ≈ 0 ops/s   droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_02Thread  thrpt:  12 738 ops/s  exportedSpans: ≈ 0 ops/s   droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_05Thread  thrpt:  31 964 ops/s  exportedSpans: ≈ 0 ops/s   droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_10Thread  thrpt:  64 101 ops/s  exportedSpans: ≈ 0 ops/s   droppedSpans: ≈ 0 ops/s   ← always zero, bug
export_20Thread  thrpt: 129 603 ops/s  exportedSpans: ≈ 0 ops/s   droppedSpans: ≈ 0 ops/s   ← always zero, bug

After fix (Type.OPERATIONS in throughput mode reports the counter rate in the same units as
the primary metric — spans/s, not spans/op. Since each operation submits exactly one span,
exportedSpans ≈ primary_thrpt, scaling linearly with thread count):

export_01Thread  thrpt:   6 367 ops/s  exportedSpans:   6 348 spans/s  droppedSpans: 0
export_02Thread  thrpt:  12 761 ops/s  exportedSpans:  12 698 spans/s  droppedSpans: 0
export_05Thread  thrpt:  31 991 ops/s  exportedSpans:  31 947 spans/s  droppedSpans: 0
export_10Thread  thrpt:  64 178 ops/s  exportedSpans:  64 102 spans/s  droppedSpans: 0
export_20Thread  thrpt: 129 033 ops/s  exportedSpans: 129 022 spans/s  droppedSpans: 0

No drops are expected — CpuBenchmark measures export throughput at a controlled low rate
(~10k spans/s per thread via parkNanos), not queue saturation. Type.OPERATIONS is the
natural unit here: the per-second rate is what a CPU profiler run reports.

Note: these are single-iteration smoke measurements (-PjmhFork=1 -PjmhWarmupIterations=1 -PjmhIterations=1 -PjmhTime=5s), so throughput scores carry more noise than the benchmark's
default 5×20s configuration.

Details

  • stringKey("dropped")booleanKey("dropped") in BatchSpanProcessorMetrics — fixes the main issue
  • AuxCounters.Type.OPERATIONSType.EVENTS in BatchSpanProcessorDroppedSpansBenchmark
    and BatchSpanProcessorMultiThreadBenchmarkType.OPERATIONS in throughput mode reports
    counter / time, so exportedSpans and droppedSpans appear in ops/s. This makes it impossible to read absolute totals. Type.EVENTS reports raw iteration totals, from which drop ratio = droppedSpans / (exportedSpans + droppedSpans).
  • numThreads derived from BenchmarkParams.getThreads() injected into @Setup(Level.Iteration)
    in all three benchmarks instead of being hardcoded in each benchmark method body — removes
    the fragile manual coupling between @Threads(N) and numThreads = N (verified:
    getThreads() correctly returns the per-method thread count, not the JMH global default)

EvgeniiR added 3 commits June 25, 2026 21:54
BatchSpanProcessorMetrics.getMetric() used stringKey("dropped") to
filter metric points, but BatchSpanProcessor records the attribute with
booleanKey("dropped"). The filter never matched, so exportedSpans and
droppedSpans always returned 0 in all BSP benchmarks since open-telemetry#3017.

- Fix stringKey → booleanKey in BatchSpanProcessorMetrics
- Remove dropRatio() — ratio does not aggregate correctly across JMH
  thread states
- Switch BatchSpanProcessorDroppedSpansBenchmark to Type.EVENTS to
  avoid integer truncation to zero in tight-loop (millions of ops/iter
  collapse per-op long counters even after the key-type fix)
- Derive numThreads from BenchmarkParams.getThreads() in @setup instead
  of hardcoding in each benchmark method body
… method

BenchmarkParams.getThreads() injected into @setup(Level.Iteration) correctly
returns the per-method @threads(N) value. Verified empirically: ratio
(exportedSpans + droppedSpans) / (primary_ops_per_sec × iteration_time) ≈ 1.0
with 5 threads. Removes the fragile manual coupling between @threads(N) and
numThreads = N scattered across each benchmark method body.
…chmark

BatchSpanProcessorMultiThreadBenchmark had the same two issues as the other
benchmarks fixed in the previous commit:
- numThreads hardcoded in each method body (fragile; same BenchmarkParams fix)
- Type.OPERATIONS reports spans/s (same unit as primary, drop rate not obvious);
  Type.EVENTS reports absolute iteration totals with clear drop rates
@EvgeniiR EvgeniiR requested a review from a team as a code owner June 25, 2026 20:24
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.97%. Comparing base (104d56e) to head (47db02e).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8539      +/-   ##
============================================
+ Coverage     90.93%   90.97%   +0.03%     
+ Complexity    10209    10208       -1     
============================================
  Files          1013     1013              
  Lines         27175    27170       -5     
  Branches       3184     3182       -2     
============================================
+ Hits          24712    24717       +5     
+ Misses         1735     1729       -6     
+ Partials        728      724       -4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Add BatchSpanProcessorMetrics.dropRatio(int numIterations), adjusting
AggregationPolicy.SUM (numThreads * numIterations) of Type.EVENTS.
Use it in DroppedSpansBenchmark and MultiThreadBenchmark, restoring
the dropRatio aux counter. CpuBenchmark stays on Type.OPERATIONS,
where the drop rate is read directly and this method does not apply.
@EvgeniiR EvgeniiR force-pushed the bsp-benchmark-aux-counters branch from 89e693c to 47db02e Compare June 26, 2026 01:26
@EvgeniiR EvgeniiR marked this pull request as ready for review June 26, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant