diff --git a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/ClientDecorator.java b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/ClientDecorator.java index 5c3dd0aaae6..3fdf47b8e22 100644 --- a/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/ClientDecorator.java +++ b/dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/decorator/ClientDecorator.java @@ -1,12 +1,24 @@ package datadog.trace.bootstrap.instrumentation.decorator; +import datadog.trace.api.TagMap; import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.Tags; public abstract class ClientDecorator extends BaseDecorator { + // Deliberately not volatile, reading a stale null and creating an extra Entry is safe + private TagMap.Entry cachedSpanKindEntry = null; protected abstract String service(); + /** Caches span kind entry to reduce allocation */ + private final TagMap.Entry spanKindEntry() { + TagMap.Entry kindEntry = cachedSpanKindEntry; + if (kindEntry == null) { + cachedSpanKindEntry = kindEntry = TagMap.Entry.create(Tags.SPAN_KIND, spanKind()); + } + return kindEntry; + } + protected String spanKind() { return Tags.SPAN_KIND_CLIENT; } @@ -16,7 +28,7 @@ public AgentSpan afterStart(final AgentSpan span) { if (service() != null) { span.setServiceName(service()); } - span.setTag(Tags.SPAN_KIND, spanKind()); + span.setTag(spanKindEntry()); // Generate metrics for all client spans. span.setMeasured(true); diff --git a/internal-api/src/test/java/datadog/trace/api/TagMapEntryTest.java b/internal-api/src/test/java/datadog/trace/api/TagMapEntryTest.java index 9eef1cb40c9..999de91f024 100644 --- a/internal-api/src/test/java/datadog/trace/api/TagMapEntryTest.java +++ b/internal-api/src/test/java/datadog/trace/api/TagMapEntryTest.java @@ -104,7 +104,7 @@ public void createEmptyCharSequence() { } @Test - public void objectEntry() { + public void newObjectEntry() { test( () -> TagMap.Entry.newObjectEntry("foo", "bar"), TagMap.Entry.OBJECT, @@ -119,7 +119,7 @@ public void objectEntry() { } @Test - @DisplayName("anyEntry: Object") + @DisplayName("newAnyEntry: Object") public void anyEntryObject() { test( () -> TagMap.Entry.newAnyEntry("foo", "bar"), @@ -155,7 +155,7 @@ public void createBoolean(boolean value) { @ValueSource(booleans = {false, true}) public void newBooleanEntry(boolean value) { test( - () -> TagMap.Entry.newBooleanEntry("foo", value), + () -> TagMap.Entry.create("foo", value), TagMap.Entry.BOOLEAN, (entry) -> multiCheck( @@ -253,7 +253,7 @@ public void newIntEntryBoxed(int value) { @ParameterizedTest @DisplayName("newIntEntry: Short") @ValueSource(shorts = {Short.MIN_VALUE, -256, -128, -1, 0, 1, 128, 256, Short.MAX_VALUE}) - public void intEntryBoxedShort(short value) { + public void newIntEntryBoxedShort(short value) { test( () -> TagMap.Entry.newIntEntry("foo", Short.valueOf(value)), TagMap.Entry.INT, @@ -269,7 +269,7 @@ public void intEntryBoxedShort(short value) { @ParameterizedTest @DisplayName("newIntEntry: Byte") @ValueSource(bytes = {Byte.MIN_VALUE, -32, -1, 0, 1, 32, Byte.MAX_VALUE}) - public void intEntryBoxedByte(byte value) { + public void newIntEntryBoxedByte(byte value) { test( () -> TagMap.Entry.newIntEntry("foo", Byte.valueOf(value)), TagMap.Entry.INT, @@ -500,7 +500,7 @@ public void createDouble(double value) { @DisplayName("newDoubleEntry: double") @ValueSource( doubles = {Double.MIN_VALUE, Float.MIN_VALUE, -1D, 0D, 1D, Math.E, Math.PI, Double.MAX_VALUE}) - public void doubleEntry(double value) { + public void newDoubleEntry(double value) { test( () -> TagMap.Entry.newDoubleEntry("foo", value), TagMap.Entry.DOUBLE, @@ -532,7 +532,7 @@ public void newDoubleEntryBoxed(double value) { @DisplayName("newAnyEntry: Double") @ValueSource( doubles = {Double.MIN_VALUE, Float.MIN_VALUE, -1D, 0D, 1D, Math.E, Math.PI, Double.MAX_VALUE}) - public void anyEntry_double(double value) { + public void newAnyEntryDouble(double value) { test( () -> TagMap.Entry.newAnyEntry("foo", Double.valueOf(value)), TagMap.Entry.ANY,