From bf07e8a76af11057ec27febfce8f84d8b8e4be01 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Fri, 19 Sep 2025 16:14:45 +0200 Subject: [PATCH 1/3] Replace StripedLongCounter with LongAdder --- ...nSubstitutionProcessorInstrumentation.java | 3 - ...ers_FixedSizeStripedLongCounterFields.java | 12 - .../common/writer/PayloadDispatcherImpl.java | 17 +- .../core/monitor/TracerHealthMetrics.java | 380 ++++++++---------- gradle/forbiddenApiFilters/main.txt | 4 + 5 files changed, 174 insertions(+), 242 deletions(-) delete mode 100644 dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields.java diff --git a/dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/AnnotationSubstitutionProcessorInstrumentation.java b/dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/AnnotationSubstitutionProcessorInstrumentation.java index fb46599f3f8..ac294cba2eb 100644 --- a/dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/AnnotationSubstitutionProcessorInstrumentation.java +++ b/dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/AnnotationSubstitutionProcessorInstrumentation.java @@ -36,7 +36,6 @@ public void methodAdvice(MethodTransformer transformer) { @Override public String[] helperClassNames() { return new String[] { - packageName + ".Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields", packageName + ".Target_datadog_jctools_util_UnsafeRefArrayAccess", packageName + ".Target_org_datadog_jmxfetch_App", packageName + ".Target_org_datadog_jmxfetch_Status", @@ -51,7 +50,6 @@ public String[] muzzleIgnoredClassNames() { "jdk.vm.ci.meta.ResolvedJavaType", "jdk.vm.ci.meta.ResolvedJavaField", // ignore helper class names as usual - packageName + ".Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields", packageName + ".Target_datadog_jctools_util_UnsafeRefArrayAccess", packageName + ".Target_org_datadog_jmxfetch_App", packageName + ".Target_org_datadog_jmxfetch_Status", @@ -62,7 +60,6 @@ public String[] muzzleIgnoredClassNames() { public static class FindTargetClassesAdvice { @Advice.OnMethodExit(suppress = Throwable.class) public static void onExit(@Advice.Return(readOnly = false) List> result) { - result.add(Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields.class); result.add(Target_datadog_jctools_util_UnsafeRefArrayAccess.class); result.add(Target_org_datadog_jmxfetch_App.class); result.add(Target_org_datadog_jmxfetch_Status.class); diff --git a/dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields.java b/dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields.java deleted file mode 100644 index 7db83f8cd97..00000000000 --- a/dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields.java +++ /dev/null @@ -1,12 +0,0 @@ -package datadog.trace.instrumentation.graal.nativeimage; - -import com.oracle.svm.core.annotate.Alias; -import com.oracle.svm.core.annotate.RecomputeFieldValue; -import com.oracle.svm.core.annotate.TargetClass; - -@TargetClass(className = "datadog.jctools.counters.FixedSizeStripedLongCounterFields") -public final class Target_datadog_jctools_counters_FixedSizeStripedLongCounterFields { - @Alias - @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.ArrayBaseOffset, declClass = long[].class) - public static long COUNTER_ARRAY_BASE; -} diff --git a/dd-trace-core/src/main/java/datadog/trace/common/writer/PayloadDispatcherImpl.java b/dd-trace-core/src/main/java/datadog/trace/common/writer/PayloadDispatcherImpl.java index dc4a4e5c6a7..a0011216770 100644 --- a/dd-trace-core/src/main/java/datadog/trace/common/writer/PayloadDispatcherImpl.java +++ b/dd-trace-core/src/main/java/datadog/trace/common/writer/PayloadDispatcherImpl.java @@ -12,8 +12,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import org.jctools.counters.CountersFactory; -import org.jctools.counters.FixedSizeStripedLongCounter; +import java.util.concurrent.atomic.LongAdder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,10 +29,8 @@ public class PayloadDispatcherImpl implements ByteBufferConsumer, PayloadDispatc private RemoteMapper mapper; private WritableFormatter packer; - private final FixedSizeStripedLongCounter droppedSpanCount = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter droppedTraceCount = - CountersFactory.createFixedSizeStripedCounter(8); + private final LongAdder droppedSpanCount = new LongAdder(); + private final LongAdder droppedTraceCount = new LongAdder(); public PayloadDispatcherImpl( RemoteMapperDiscovery mapperDiscovery, @@ -60,8 +57,8 @@ public Collection getApis() { @Override public void onDroppedTrace(int spanCount) { - droppedSpanCount.inc(spanCount); - droppedTraceCount.inc(); + droppedSpanCount.add(spanCount); + droppedTraceCount.increment(); } @Override @@ -97,8 +94,8 @@ Payload newPayload(int messageCount, ByteBuffer buffer) { return mapper .newPayload() .withBody(messageCount, buffer) - .withDroppedSpans(droppedSpanCount.getAndReset()) - .withDroppedTraces(droppedTraceCount.getAndReset()); + .withDroppedSpans(droppedSpanCount.sumThenReset()) + .withDroppedTraces(droppedTraceCount.sumThenReset()); } @Override diff --git a/dd-trace-core/src/main/java/datadog/trace/core/monitor/TracerHealthMetrics.java b/dd-trace-core/src/main/java/datadog/trace/core/monitor/TracerHealthMetrics.java index 3190486e3fd..409553cbb0d 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/monitor/TracerHealthMetrics.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/monitor/TracerHealthMetrics.java @@ -17,9 +17,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.LongAdder; import java.util.function.IntFunction; -import org.jctools.counters.CountersFactory; -import org.jctools.counters.FixedSizeStripedLongCounter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,115 +36,65 @@ public class TracerHealthMetrics extends HealthMetrics implements AutoCloseable private final AtomicBoolean started = new AtomicBoolean(false); private volatile AgentTaskScheduler.Scheduled cancellation; - private final FixedSizeStripedLongCounter apiRequests = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter apiErrors = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter apiResponsesOK = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter userDropEnqueuedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter userKeepEnqueuedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter samplerDropEnqueuedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter samplerKeepEnqueuedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter unsetPriorityEnqueuedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter userDropDroppedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter userKeepDroppedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter samplerDropDroppedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter samplerKeepDroppedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter serialFailedDroppedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter unsetPriorityDroppedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter userDropDroppedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter userKeepDroppedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter samplerDropDroppedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter samplerKeepDroppedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter serialFailedDroppedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter unsetPriorityDroppedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter enqueuedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter enqueuedBytes = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter createdTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter createdSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter finishedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter flushedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter flushedBytes = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter partialTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter partialBytes = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter clientSpansWithoutContext = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter singleSpanSampled = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter singleSpanUnsampled = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter capturedContinuations = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter cancelledContinuations = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter finishedContinuations = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter activatedScopes = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter closedScopes = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter scopeStackOverflow = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter scopeCloseErrors = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter userScopeCloseErrors = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter longRunningTracesWrite = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter longRunningTracesDropped = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter longRunningTracesExpired = - CountersFactory.createFixedSizeStripedCounter(8); - - private final FixedSizeStripedLongCounter clientStatsProcessedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter clientStatsProcessedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter clientStatsP0DroppedSpans = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter clientStatsP0DroppedTraces = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter clientStatsRequests = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter clientStatsErrors = - CountersFactory.createFixedSizeStripedCounter(8); - private final FixedSizeStripedLongCounter clientStatsDowngrades = - CountersFactory.createFixedSizeStripedCounter(8); + private final LongAdder apiRequests = new LongAdder(); + private final LongAdder apiErrors = new LongAdder(); + private final LongAdder apiResponsesOK = new LongAdder(); + + private final LongAdder userDropEnqueuedTraces = new LongAdder(); + private final LongAdder userKeepEnqueuedTraces = new LongAdder(); + private final LongAdder samplerDropEnqueuedTraces = new LongAdder(); + private final LongAdder samplerKeepEnqueuedTraces = new LongAdder(); + private final LongAdder unsetPriorityEnqueuedTraces = new LongAdder(); + + private final LongAdder userDropDroppedTraces = new LongAdder(); + private final LongAdder userKeepDroppedTraces = new LongAdder(); + private final LongAdder samplerDropDroppedTraces = new LongAdder(); + private final LongAdder samplerKeepDroppedTraces = new LongAdder(); + private final LongAdder serialFailedDroppedTraces = new LongAdder(); + private final LongAdder unsetPriorityDroppedTraces = new LongAdder(); + + private final LongAdder userDropDroppedSpans = new LongAdder(); + private final LongAdder userKeepDroppedSpans = new LongAdder(); + private final LongAdder samplerDropDroppedSpans = new LongAdder(); + private final LongAdder samplerKeepDroppedSpans = new LongAdder(); + private final LongAdder serialFailedDroppedSpans = new LongAdder(); + private final LongAdder unsetPriorityDroppedSpans = new LongAdder(); + + private final LongAdder enqueuedSpans = new LongAdder(); + private final LongAdder enqueuedBytes = new LongAdder(); + private final LongAdder createdTraces = new LongAdder(); + private final LongAdder createdSpans = new LongAdder(); + private final LongAdder finishedSpans = new LongAdder(); + private final LongAdder flushedTraces = new LongAdder(); + private final LongAdder flushedBytes = new LongAdder(); + private final LongAdder partialTraces = new LongAdder(); + private final LongAdder partialBytes = new LongAdder(); + private final LongAdder clientSpansWithoutContext = new LongAdder(); + + private final LongAdder singleSpanSampled = new LongAdder(); + private final LongAdder singleSpanUnsampled = new LongAdder(); + + private final LongAdder capturedContinuations = new LongAdder(); + private final LongAdder cancelledContinuations = new LongAdder(); + private final LongAdder finishedContinuations = new LongAdder(); + + private final LongAdder activatedScopes = new LongAdder(); + private final LongAdder closedScopes = new LongAdder(); + private final LongAdder scopeStackOverflow = new LongAdder(); + private final LongAdder scopeCloseErrors = new LongAdder(); + private final LongAdder userScopeCloseErrors = new LongAdder(); + + private final LongAdder longRunningTracesWrite = new LongAdder(); + private final LongAdder longRunningTracesDropped = new LongAdder(); + private final LongAdder longRunningTracesExpired = new LongAdder(); + + private final LongAdder clientStatsProcessedSpans = new LongAdder(); + private final LongAdder clientStatsProcessedTraces = new LongAdder(); + private final LongAdder clientStatsP0DroppedSpans = new LongAdder(); + private final LongAdder clientStatsP0DroppedTraces = new LongAdder(); + private final LongAdder clientStatsRequests = new LongAdder(); + private final LongAdder clientStatsErrors = new LongAdder(); + private final LongAdder clientStatsDowngrades = new LongAdder(); private final StatsDClient statsd; private final long interval; @@ -182,21 +131,21 @@ public void onShutdown(final boolean flushSuccess) {} public void onPublish(final List trace, final int samplingPriority) { switch (samplingPriority) { case USER_DROP: - userDropEnqueuedTraces.inc(); + userDropEnqueuedTraces.increment(); break; case USER_KEEP: - userKeepEnqueuedTraces.inc(); + userKeepEnqueuedTraces.increment(); break; case SAMPLER_DROP: - samplerDropEnqueuedTraces.inc(); + samplerDropEnqueuedTraces.increment(); break; case SAMPLER_KEEP: - samplerKeepEnqueuedTraces.inc(); + samplerKeepEnqueuedTraces.increment(); break; default: - unsetPriorityEnqueuedTraces.inc(); + unsetPriorityEnqueuedTraces.increment(); } - enqueuedSpans.inc(trace.size()); + enqueuedSpans.add(trace.size()); checkForClientSpansWithoutContext(trace); } @@ -205,7 +154,7 @@ private void checkForClientSpansWithoutContext(final List trace) { if (span != null && span.getParentId() == ZERO) { String spanKind = span.getTag(SPAN_KIND, "undefined"); if (SPAN_KIND_CLIENT.equals(spanKind)) { - this.clientSpansWithoutContext.inc(); + this.clientSpansWithoutContext.increment(); } } } @@ -215,31 +164,31 @@ private void checkForClientSpansWithoutContext(final List trace) { public void onFailedPublish(final int samplingPriority, final int spanCount) { switch (samplingPriority) { case USER_DROP: - userDropDroppedSpans.inc(spanCount); - userDropDroppedTraces.inc(); + userDropDroppedSpans.add(spanCount); + userDropDroppedTraces.increment(); break; case USER_KEEP: - userKeepDroppedSpans.inc(spanCount); - userKeepDroppedTraces.inc(); + userKeepDroppedSpans.add(spanCount); + userKeepDroppedTraces.increment(); break; case SAMPLER_DROP: - samplerDropDroppedSpans.inc(spanCount); - samplerDropDroppedTraces.inc(); + samplerDropDroppedSpans.add(spanCount); + samplerDropDroppedTraces.increment(); break; case SAMPLER_KEEP: - samplerKeepDroppedSpans.inc(spanCount); - samplerKeepDroppedTraces.inc(); + samplerKeepDroppedSpans.add(spanCount); + samplerKeepDroppedTraces.increment(); break; default: - unsetPriorityDroppedSpans.inc(spanCount); - unsetPriorityDroppedTraces.inc(); + unsetPriorityDroppedSpans.add(spanCount); + unsetPriorityDroppedTraces.increment(); } } @Override public void onPartialPublish(final int numberOfDroppedSpans) { - partialTraces.inc(); - samplerDropDroppedSpans.inc(numberOfDroppedSpans); + partialTraces.increment(); + samplerDropDroppedSpans.add(numberOfDroppedSpans); } @Override @@ -252,85 +201,85 @@ public void onFlush(final boolean early) {} @Override public void onPartialFlush(final int sizeInBytes) { - partialBytes.inc(sizeInBytes); + partialBytes.add(sizeInBytes); } @Override public void onSingleSpanSample() { - singleSpanSampled.inc(); + singleSpanSampled.increment(); } @Override public void onSingleSpanUnsampled() { - singleSpanUnsampled.inc(); + singleSpanUnsampled.increment(); } @Override public void onSerialize(final int serializedSizeInBytes) { // DQH - Because of Java tracer's 2 phase acceptance and serialization scheme, this doesn't // map precisely - enqueuedBytes.inc(serializedSizeInBytes); + enqueuedBytes.add(serializedSizeInBytes); } @Override public void onFailedSerialize(final List trace, final Throwable optionalCause) { if (trace != null) { - serialFailedDroppedTraces.inc(); - serialFailedDroppedSpans.inc(trace.size()); + serialFailedDroppedTraces.increment(); + serialFailedDroppedSpans.add(trace.size()); } } @Override public void onCreateSpan() { - createdSpans.inc(); + createdSpans.increment(); } @Override public void onFinishSpan() { - finishedSpans.inc(); + finishedSpans.increment(); } @Override public void onCreateTrace() { - createdTraces.inc(); + createdTraces.increment(); } @Override public void onScopeCloseError(boolean manual) { - scopeCloseErrors.inc(); + scopeCloseErrors.increment(); if (manual) { - userScopeCloseErrors.inc(); + userScopeCloseErrors.increment(); } } @Override public void onCaptureContinuation() { - capturedContinuations.inc(); + capturedContinuations.increment(); } @Override public void onCancelContinuation() { - cancelledContinuations.inc(); + cancelledContinuations.increment(); } @Override public void onFinishContinuation() { - finishedContinuations.inc(); + finishedContinuations.increment(); } @Override public void onActivateScope() { - activatedScopes.inc(); + activatedScopes.increment(); } @Override public void onCloseScope() { - closedScopes.inc(); + closedScopes.increment(); } @Override public void onScopeStackOverflow() { - scopeStackOverflow.inc(); + scopeStackOverflow.increment(); } @Override @@ -347,28 +296,28 @@ public void onFailedSend( @Override public void onLongRunningUpdate(final int dropped, final int write, final int expired) { - longRunningTracesWrite.inc(write); - longRunningTracesDropped.inc(dropped); - longRunningTracesExpired.inc(expired); + longRunningTracesWrite.add(write); + longRunningTracesDropped.add(dropped); + longRunningTracesExpired.add(expired); } private void onSendAttempt( final int traceCount, final int sizeInBytes, final RemoteApi.Response response) { - apiRequests.inc(); - flushedTraces.inc(traceCount); + apiRequests.increment(); + flushedTraces.add(traceCount); // TODO: missing queue.spans (# of spans being sent) - flushedBytes.inc(sizeInBytes); + flushedBytes.add(sizeInBytes); if (response.exception() != null) { // covers communication errors -- both not receiving a response or // receiving malformed response (even when otherwise successful) - apiErrors.inc(); + apiErrors.increment(); } Integer status = response.status(); if (status != null) { if (200 == status) { - apiResponsesOK.inc(); + apiResponsesOK.increment(); } else { statsd.incrementCounter("api.responses.total", statusTagsCache.get(status)); } @@ -377,27 +326,27 @@ private void onSendAttempt( @Override public void onClientStatTraceComputed(int countedSpans, int totalSpans, boolean dropped) { - clientStatsProcessedTraces.inc(); - clientStatsProcessedSpans.inc(countedSpans); + clientStatsProcessedTraces.increment(); + clientStatsProcessedSpans.add(countedSpans); if (dropped) { - clientStatsP0DroppedTraces.inc(); - clientStatsP0DroppedSpans.inc(totalSpans); + clientStatsP0DroppedTraces.increment(); + clientStatsP0DroppedSpans.add(totalSpans); } } @Override public void onClientStatPayloadSent() { - clientStatsRequests.inc(); + clientStatsRequests.increment(); } @Override public void onClientStatDowngraded() { - clientStatsDowngrades.inc(); + clientStatsDowngrades.increment(); } @Override public void onClientStatErrorReceived() { - clientStatsErrors.inc(); + clientStatsErrors.increment(); } @Override @@ -549,11 +498,8 @@ public void run(TracerHealthMetrics target) { } private void reportIfChanged( - StatsDClient statsDClient, - String aspect, - FixedSizeStripedLongCounter counter, - String[] tags) { - long count = counter.get(); + StatsDClient statsDClient, String aspect, LongAdder counter, String[] tags) { + long count = counter.sum(); long delta = count - previousCounts[++countIndex]; if (delta > 0) { statsDClient.count(aspect, delta, tags); @@ -565,114 +511,114 @@ private void reportIfChanged( @Override public String summary() { return "apiRequests=" - + apiRequests.get() + + apiRequests.sum() + "\napiErrors=" - + apiErrors.get() + + apiErrors.sum() + "\napiResponsesOK=" - + apiResponsesOK.get() + + apiResponsesOK.sum() + "\n" + "\nuserDropEnqueuedTraces=" - + userDropEnqueuedTraces.get() + + userDropEnqueuedTraces.sum() + "\nuserKeepEnqueuedTraces=" - + userKeepEnqueuedTraces.get() + + userKeepEnqueuedTraces.sum() + "\nsamplerDropEnqueuedTraces=" - + samplerDropEnqueuedTraces.get() + + samplerDropEnqueuedTraces.sum() + "\nsamplerKeepEnqueuedTraces=" - + samplerKeepEnqueuedTraces.get() + + samplerKeepEnqueuedTraces.sum() + "\nunsetPriorityEnqueuedTraces=" - + unsetPriorityEnqueuedTraces.get() + + unsetPriorityEnqueuedTraces.sum() + "\n" + "\nuserDropDroppedTraces=" - + userDropDroppedTraces.get() + + userDropDroppedTraces.sum() + "\nuserKeepDroppedTraces=" - + userKeepDroppedTraces.get() + + userKeepDroppedTraces.sum() + "\nsamplerDropDroppedTraces=" - + samplerDropDroppedTraces.get() + + samplerDropDroppedTraces.sum() + "\nsamplerKeepDroppedTraces=" - + samplerKeepDroppedTraces.get() + + samplerKeepDroppedTraces.sum() + "\nserialFailedDroppedTraces=" - + serialFailedDroppedTraces.get() + + serialFailedDroppedTraces.sum() + "\nunsetPriorityDroppedTraces=" - + unsetPriorityDroppedTraces.get() + + unsetPriorityDroppedTraces.sum() + "\n" + "\nuserDropDroppedSpans=" - + userDropDroppedSpans.get() + + userDropDroppedSpans.sum() + "\nuserKeepDroppedSpans=" - + userKeepDroppedSpans.get() + + userKeepDroppedSpans.sum() + "\nsamplerDropDroppedSpans=" - + samplerDropDroppedSpans.get() + + samplerDropDroppedSpans.sum() + "\nsamplerKeepDroppedSpans=" - + samplerKeepDroppedSpans.get() + + samplerKeepDroppedSpans.sum() + "\nserialFailedDroppedSpans=" - + serialFailedDroppedSpans.get() + + serialFailedDroppedSpans.sum() + "\nunsetPriorityDroppedSpans=" - + unsetPriorityDroppedSpans.get() + + unsetPriorityDroppedSpans.sum() + "\n" + "\nenqueuedSpans=" - + enqueuedSpans.get() + + enqueuedSpans.sum() + "\nenqueuedBytes=" - + enqueuedBytes.get() + + enqueuedBytes.sum() + "\ncreatedTraces=" - + createdTraces.get() + + createdTraces.sum() + "\ncreatedSpans=" - + createdSpans.get() + + createdSpans.sum() + "\nfinishedSpans=" - + finishedSpans.get() + + finishedSpans.sum() + "\nflushedTraces=" - + flushedTraces.get() + + flushedTraces.sum() + "\nflushedBytes=" - + flushedBytes.get() + + flushedBytes.sum() + "\npartialTraces=" - + partialTraces.get() + + partialTraces.sum() + "\npartialBytes=" - + partialBytes.get() + + partialBytes.sum() + "\n" + "\nclientSpansWithoutContext=" - + clientSpansWithoutContext.get() + + clientSpansWithoutContext.sum() + "\n" + "\nsingleSpanSampled=" - + singleSpanSampled.get() + + singleSpanSampled.sum() + "\nsingleSpanUnsampled=" - + singleSpanUnsampled.get() + + singleSpanUnsampled.sum() + "\n" + "\ncapturedContinuations=" - + capturedContinuations.get() + + capturedContinuations.sum() + "\ncancelledContinuations=" - + cancelledContinuations.get() + + cancelledContinuations.sum() + "\nfinishedContinuations=" - + finishedContinuations.get() + + finishedContinuations.sum() + "\n" + "\nactivatedScopes=" - + activatedScopes.get() + + activatedScopes.sum() + "\nclosedScopes=" - + closedScopes.get() + + closedScopes.sum() + "\nscopeStackOverflow=" - + scopeStackOverflow.get() + + scopeStackOverflow.sum() + "\nscopeCloseErrors=" - + scopeCloseErrors.get() + + scopeCloseErrors.sum() + "\nuserScopeCloseErrors=" - + userScopeCloseErrors.get() + + userScopeCloseErrors.sum() + "\n" + "\nlongRunningTracesWrite=" - + longRunningTracesWrite.get() + + longRunningTracesWrite.sum() + "\nlongRunningTracesDropped=" - + longRunningTracesDropped.get() + + longRunningTracesDropped.sum() + "\nlongRunningTracesExpired=" - + longRunningTracesExpired.get() + + longRunningTracesExpired.sum() + "\n" + "\nclientStatsRequests=" - + clientStatsRequests.get() + + clientStatsRequests.sum() + "\nclientStatsErrors=" - + clientStatsErrors.get() + + clientStatsErrors.sum() + "\nclientStatsDowngrades=" - + clientStatsDowngrades.get() + + clientStatsDowngrades.sum() + "\nclientStatsP0DroppedSpans=" - + clientStatsP0DroppedSpans.get() + + clientStatsP0DroppedSpans.sum() + "\nclientStatsP0DroppedTraces=" - + clientStatsP0DroppedTraces.get() + + clientStatsP0DroppedTraces.sum() + "\nclientStatsProcessedSpans=" - + clientStatsProcessedSpans.get() + + clientStatsProcessedSpans.sum() + "\nclientStatsProcessedTraces=" - + clientStatsProcessedTraces.get(); + + clientStatsProcessedTraces.sum(); } } diff --git a/gradle/forbiddenApiFilters/main.txt b/gradle/forbiddenApiFilters/main.txt index 4993b965ed8..2cffd42a752 100644 --- a/gradle/forbiddenApiFilters/main.txt +++ b/gradle/forbiddenApiFilters/main.txt @@ -28,3 +28,7 @@ net.bytebuddy.matcher.ElementMatchers#isAbstract() @defaultMessage Avoid using System.out/err to prevent excess logging. To override, add @SuppressForbidden. java.lang.System#out java.lang.System#err + +#Use jdk LongAdder +@defaultMessage use LongAdder instead of the legacy jctools FixedSizeStripedLongCounter +org.jctools.counters.FixedSizeStripedLongCounter From b82f68e06544ba6ca36825d4d2e7389a0b098180 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Fri, 19 Sep 2025 16:41:50 +0200 Subject: [PATCH 2/3] Add microbench --- .../trace/common/LongAdderBenchmark.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java diff --git a/dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java b/dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java new file mode 100644 index 00000000000..cd368f9b5f7 --- /dev/null +++ b/dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java @@ -0,0 +1,66 @@ +package datadog.trace.common; + +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import de.thetaphi.forbiddenapis.SuppressForbidden; +import java.util.concurrent.atomic.LongAdder; +import org.jctools.counters.CountersFactory; +import org.jctools.counters.FixedSizeStripedLongCounter; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Threads; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +/** + * Benchmark Mode Cnt Score Error Units + * LongAdderBenchmark.benchLongAdderIncrement avgt 0.009 us/op + * LongAdderBenchmark.benchLongAdderSum avgt 0.297 us/op + * LongAdderBenchmark.benchStripedCounterIncrement avgt 0.071 us/op + * LongAdderBenchmark.benchStripedCounterSum avgt 0.425 us/op + */ +@State(Scope.Benchmark) +@Warmup(iterations = 1, time = 30, timeUnit = SECONDS) +@Measurement(iterations = 1, time = 30, timeUnit = SECONDS) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(MICROSECONDS) +@Fork(value = 1) +@SuppressForbidden +public class LongAdderBenchmark { + public final LongAdder adder = new LongAdder(); + public final FixedSizeStripedLongCounter counter = + CountersFactory.createFixedSizeStripedCounter(8); + + @Benchmark + @Threads(Threads.MAX) + public void benchLongAdderIncrement(Blackhole blackhole) { + adder.increment(); + } + + @Benchmark + @Threads(Threads.MAX) + public void benchStripedCounterIncrement(Blackhole blackhole) { + counter.inc(); + } + + @Benchmark + @Threads(Threads.MAX) + public void benchLongAdderSum(Blackhole blackhole) { + adder.increment(); + blackhole.consume(adder.sum()); + } + + @Benchmark + @Threads(Threads.MAX) + public void benchStripedCounterSum(Blackhole blackhole) { + counter.inc(); + blackhole.consume(counter.get()); + } +} From 771c01264c45bc509361f7145476362f35e152d2 Mon Sep 17 00:00:00 2001 From: Andrea Marziali Date: Fri, 19 Sep 2025 16:48:15 +0200 Subject: [PATCH 3/3] spotless - convert to normal comment --- .../src/jmh/java/datadog/trace/common/LongAdderBenchmark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java b/dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java index cd368f9b5f7..beb424740ca 100644 --- a/dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java +++ b/dd-trace-core/src/jmh/java/datadog/trace/common/LongAdderBenchmark.java @@ -19,7 +19,7 @@ import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.infra.Blackhole; -/** +/* * Benchmark Mode Cnt Score Error Units * LongAdderBenchmark.benchLongAdderIncrement avgt 0.009 us/op * LongAdderBenchmark.benchLongAdderSum avgt 0.297 us/op