ProbabilisticSampleRate implements SamplingStrategy { @Override public boolean shouldSample() { long lastSampledAt = lastSampledAtNanoTime.get(); long now = nanoClock.nanoTimeNow(); double secsSinceLastSample = (now - lastSampledAt) / 1_000_000_000.0; double sampleProb = Math.min(secsSinceLastSample * desiredSamplesPerSec, 1.0); if (randomSupplier.get().nextDouble() < sampleProb) { lastSampledAtNanoTime.set(now); return true; } else { return false; } } ProbabilisticSampleRate(MonotonicNanoClock nanoClock,
                                   Supplier<Random> randomSupplier,
                                   double desiredSamplesPerSec); static ProbabilisticSampleRate withSystemDefaults(double desiredSamplesPerSec); @Override boolean shouldSample();  }
@Test public void samples_are_rate_limited_per_second() { var clock = MockUtils.mockedClockReturning(ms2ns(10_000), ms2ns(10_500), ms2ns(10_500), ms2ns(10_501)); var rng = MockUtils.mockedRandomReturning(0.1, 0.51, 0.49, 0.01); var sampler = new ProbabilisticSampleRate(clock, () -> rng, 1.0); assertTrue(sampler.shouldSample()); assertFalse(sampler.shouldSample()); assertTrue(sampler.shouldSample()); assertFalse(sampler.shouldSample()); }
@Test public void zero_desired_sample_rate_returns_false() { var clock = MockUtils.mockedClockReturning(ms2ns(10_000)); var rng = MockUtils.mockedRandomReturning(0.99999999); var sampler = new ProbabilisticSampleRate(clock, () -> rng, 0.0); assertFalse(sampler.shouldSample()); }