From 7ff0dc2acf247f15a0216c006458597f127d75d8 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Fri, 24 Mar 2023 09:18:29 -0700 Subject: [PATCH] Decouple session id name (#505) * Make default attribute "rum.session.id". * spotless * keep existing attribute * spotless --- .../splunk/rum/SplunkSpanDataModifier.java | 5 ++ .../com/splunk/rum/StandardAttributes.java | 10 ++- .../rum/internal/RumConstants.java | 2 + .../rum/internal/SessionIdSpanAppender.java | 6 +- .../rum/SplunkSpanDataModifierTest.java | 62 ++++++++++++------- .../internal/OpenTelemetryRumBuilderTest.java | 4 +- .../internal/SessionIdSpanAppenderTest.java | 3 +- 7 files changed, 58 insertions(+), 34 deletions(-) diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java index fd9e5a2b2..30e291ad9 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/SplunkSpanDataModifier.java @@ -29,6 +29,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.rum.internal.RumConstants; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.data.DelegatingSpanData; import io.opentelemetry.sdk.trace.data.EventData; @@ -81,6 +82,10 @@ private SpanData modify(SpanData original) { List modifiedEvents = new ArrayList<>(original.getEvents().size()); AttributesBuilder modifiedAttributes = original.getAttributes().toBuilder(); + // Copy the native session id name into the splunk name + String sessionId = original.getAttributes().get(RumConstants.SESSION_ID_KEY); + modifiedAttributes.put(StandardAttributes.SESSION_ID_KEY, sessionId); + SpanContext spanContext; if (reactNativeEnabled) { spanContext = extractReactNativeIdsIfPresent(original); diff --git a/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java b/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java index 46a69e237..7c3186a23 100644 --- a/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java +++ b/splunk-otel-android/src/main/java/com/splunk/rum/StandardAttributes.java @@ -16,6 +16,8 @@ package com.splunk.rum; +import static io.opentelemetry.api.common.AttributeKey.stringKey; + import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.rum.internal.SpanFilterBuilder; @@ -31,7 +33,7 @@ public final class StandardAttributes { * * @see SplunkRumBuilder#setGlobalAttributes(Attributes) */ - public static final AttributeKey APP_VERSION = AttributeKey.stringKey("app.version"); + public static final AttributeKey APP_VERSION = stringKey("app.version"); /** * The build type of your app (typically one of debug or release). Useful for adding to global @@ -39,8 +41,7 @@ public final class StandardAttributes { * * @see SplunkRumBuilder#setGlobalAttributes(Attributes) */ - public static final AttributeKey APP_BUILD_TYPE = - AttributeKey.stringKey("app.build.type"); + public static final AttributeKey APP_BUILD_TYPE = stringKey("app.build.type"); /** * Full HTTP client request URL in the form {@code scheme://host[:port]/path?query[#fragment]}. @@ -50,5 +51,8 @@ public final class StandardAttributes { */ public static final AttributeKey HTTP_URL = SemanticAttributes.HTTP_URL; + public static final AttributeKey SESSION_ID_KEY = + stringKey("splunk.rumSessionId"); + private StandardAttributes() {} } diff --git a/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/RumConstants.java b/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/RumConstants.java index caefa01ef..2cd941182 100644 --- a/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/RumConstants.java +++ b/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/RumConstants.java @@ -24,6 +24,8 @@ public class RumConstants { public static final String OTEL_RUM_LOG_TAG = "OpenTelemetryRum"; + public static final AttributeKey SESSION_ID_KEY = stringKey("rum.session.id"); + public static final AttributeKey LAST_SCREEN_NAME_KEY = AttributeKey.stringKey("last.screen.name"); public static final AttributeKey SCREEN_NAME_KEY = diff --git a/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java b/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java index c4494e092..b6acd7fca 100644 --- a/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java +++ b/splunk-otel-android/src/main/java/io/opentelemetry/rum/internal/SessionIdSpanAppender.java @@ -16,9 +16,8 @@ package io.opentelemetry.rum.internal; -import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.rum.internal.RumConstants.SESSION_ID_KEY; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.context.Context; import io.opentelemetry.sdk.trace.ReadWriteSpan; import io.opentelemetry.sdk.trace.ReadableSpan; @@ -26,9 +25,6 @@ final class SessionIdSpanAppender implements SpanProcessor { - // TODO: rename to something that is not splunk specific - static final AttributeKey SESSION_ID_KEY = stringKey("splunk.rumSessionId"); - private final SessionId sessionId; public SessionIdSpanAppender(SessionId sessionId) { diff --git a/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java b/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java index ffd161f39..ce6a92cc9 100644 --- a/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java +++ b/splunk-otel-android/src/test/java/com/splunk/rum/SplunkSpanDataModifierTest.java @@ -23,6 +23,7 @@ import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; import static org.mockito.Mockito.when; import io.opentelemetry.api.common.Attributes; @@ -30,6 +31,7 @@ import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.rum.internal.RumConstants; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.trace.TestSpanData; @@ -54,16 +56,30 @@ class SplunkSpanDataModifierTest { @Mock private SpanExporter delegate; @Captor private ArgumentCaptor> exportedSpansCaptor; + @Test + void changesSpanIdAttrName() { + String sessionId = "abc123fonzie"; + Attributes attrs = Attributes.of(RumConstants.SESSION_ID_KEY, sessionId); + SpanData original = startBuilder().setAttributes(attrs).build(); + + CompletableResultCode exportResult = CompletableResultCode.ofSuccess(); + when(delegate.export(exportedSpansCaptor.capture())).thenReturn(exportResult); + + SplunkSpanDataModifier underTest = new SplunkSpanDataModifier(delegate, false); + underTest.export(singletonList(original)); + + Collection exported = exportedSpansCaptor.getValue(); + assertThat(exported).hasSize(1); + SpanData first = exported.iterator().next(); + assertThat(first.getAttributes().get(StandardAttributes.SESSION_ID_KEY)) + .isEqualTo(sessionId); + assertThat(first.getAttributes().get(RumConstants.SESSION_ID_KEY)).isEqualTo(sessionId); + } + @Test void shouldConvertExceptionEventsToSpanAttributes() { SpanData original = - TestSpanData.builder() - .setName("test") - .setKind(SpanKind.CLIENT) - .setStatus(StatusData.unset()) - .setStartEpochNanos(12345) - .setEndEpochNanos(67890) - .setHasEnded(true) + startBuilder() .setEvents( Arrays.asList( EventData.create( @@ -119,15 +135,7 @@ void shouldConvertExceptionEventsToSpanAttributes() { @Test void shouldSetCaseSensitiveSpanNameToAttribute() { - SpanData original = - TestSpanData.builder() - .setName("SplunkRumSpan") - .setKind(SpanKind.CLIENT) - .setStatus(StatusData.unset()) - .setStartEpochNanos(12345) - .setEndEpochNanos(67890) - .setHasEnded(true) - .build(); + SpanData original = startBuilder("SplunkRumSpan").build(); CompletableResultCode exportResult = CompletableResultCode.ofSuccess(); when(delegate.export(exportedSpansCaptor.capture())).thenReturn(exportResult); @@ -206,14 +214,8 @@ void shouldIgnoreReactIdsIfReactNativeSupportIsDisabled() { TraceState.getDefault()); SpanData original = - TestSpanData.builder() + startBuilder("SplunkRumSpan") .setSpanContext(spanContext) - .setName("SplunkRumSpan") - .setKind(SpanKind.CLIENT) - .setStatus(StatusData.unset()) - .setStartEpochNanos(12345) - .setEndEpochNanos(67890) - .setHasEnded(true) .setAttributes( Attributes.builder() .put( @@ -286,4 +288,18 @@ void shouldReplaceTraceAndSpanIdWithReactNativeIds() { .hasSpanId("8888888888888888") .hasAttributesSatisfyingExactly(equalTo(SPLUNK_OPERATION_KEY, "SplunkRumSpan")); } + + private TestSpanData.Builder startBuilder() { + return startBuilder("test"); + } + + private TestSpanData.Builder startBuilder(String name) { + return TestSpanData.builder() + .setName(name) + .setKind(SpanKind.CLIENT) + .setStatus(StatusData.unset()) + .setStartEpochNanos(12345) + .setEndEpochNanos(67890) + .setHasEnded(true); + } } diff --git a/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java b/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java index e259e94fa..ca9fa2ee3 100644 --- a/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java +++ b/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/OpenTelemetryRumBuilderTest.java @@ -16,6 +16,7 @@ package io.opentelemetry.rum.internal; +import static io.opentelemetry.rum.internal.RumConstants.SESSION_ID_KEY; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static org.mockito.ArgumentMatchers.isA; @@ -80,8 +81,7 @@ void shouldBuildTracerProvider() { assertThat(spans.get(0)) .hasName("test span") .hasResource(resource) - .hasAttributesSatisfyingExactly( - equalTo(SessionIdSpanAppender.SESSION_ID_KEY, sessionId)); + .hasAttributesSatisfyingExactly(equalTo(SESSION_ID_KEY, sessionId)); } @Test diff --git a/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java b/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java index f5eb77639..c065113b0 100644 --- a/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java +++ b/splunk-otel-android/src/test/java/io/opentelemetry/rum/internal/SessionIdSpanAppenderTest.java @@ -16,6 +16,7 @@ package io.opentelemetry.rum.internal; +import static io.opentelemetry.rum.internal.RumConstants.SESSION_ID_KEY; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.verify; @@ -43,7 +44,7 @@ void shouldSetSessionIdAsSpanAttribute() { assertTrue(underTest.isStartRequired()); underTest.onStart(Context.root(), span); - verify(span).setAttribute(SessionIdSpanAppender.SESSION_ID_KEY, "42"); + verify(span).setAttribute(SESSION_ID_KEY, "42"); assertFalse(underTest.isEndRequired()); }