diff --git a/profiler/src/main/java/com/splunk/opentelemetry/profiler/Configuration.java b/profiler/src/main/java/com/splunk/opentelemetry/profiler/Configuration.java index 17a36af1f..c25014cc1 100644 --- a/profiler/src/main/java/com/splunk/opentelemetry/profiler/Configuration.java +++ b/profiler/src/main/java/com/splunk/opentelemetry/profiler/Configuration.java @@ -66,7 +66,7 @@ public static void log(ConfigProperties config) { log(CONFIG_KEY_RECORDING_DURATION, getRecordingDuration(config).toMillis() + "ms"); log(CONFIG_KEY_KEEP_FILES, getKeepFiles(config)); log(CONFIG_KEY_PROFILER_OTLP_PROTOCOL, getOtlpProtocol(config)); - log(CONFIG_KEY_INGEST_URL, getConfigUrl(config)); + log(CONFIG_KEY_INGEST_URL, getIngestUrl(config)); log(CONFIG_KEY_OTEL_OTLP_URL, config.getString(CONFIG_KEY_OTEL_OTLP_URL)); log(CONFIG_KEY_MEMORY_ENABLED, getMemoryEnabled(config)); if (getMemoryEventRateLimitEnabled(config)) { @@ -85,27 +85,40 @@ private static void log(String key, @Nullable Object value) { logger.info(String.format("%39s : %s", key, value)); } - public static String getConfigUrl(ConfigProperties config) { - String ingestUrl = config.getString(CONFIG_KEY_OTEL_OTLP_URL); - if (ingestUrl != null) { - if (ingestUrl.startsWith("https://ingest.") - && ingestUrl.endsWith(".signalfx.com") - && config.getString(CONFIG_KEY_INGEST_URL) == null) { + public static String getIngestUrl(ConfigProperties config) { + String ingestUrl = config.getString(CONFIG_KEY_INGEST_URL); + + if (ingestUrl == null) { + String defaultIngestUrl = getDefaultLogsEndpoint(config); + ingestUrl = config.getString(CONFIG_KEY_OTEL_OTLP_URL, defaultIngestUrl); + + if (ingestUrl.startsWith("https://ingest.") && ingestUrl.endsWith(".signalfx.com")) { logger.log( WARNING, "Profiling data can not be sent to {0}, using {1} instead. " - + "You can override it by setting splunk.profiler.logs-endpoint", - new Object[] {ingestUrl, getDefaultLogsEndpoint(config)}); - return null; + + "You can override it by setting " + + CONFIG_KEY_INGEST_URL, + new Object[] {ingestUrl, defaultIngestUrl}); + return defaultIngestUrl; } + if ("http/protobuf".equals(getOtlpProtocol(config))) { - if (!ingestUrl.endsWith("/")) { - ingestUrl += "/"; - } - ingestUrl += "v1/logs"; + ingestUrl = maybeAppendHttpPath(ingestUrl); } } - return config.getString(CONFIG_KEY_INGEST_URL, ingestUrl); + + return ingestUrl; + } + + private static String maybeAppendHttpPath(String ingestUrl) { + if (!ingestUrl.endsWith("v1/logs")) { + if (!ingestUrl.endsWith("/")) { + ingestUrl += "/"; + } + ingestUrl += "v1/logs"; + } + + return ingestUrl; } private static String getDefaultLogsEndpoint(ConfigProperties config) { diff --git a/profiler/src/main/java/com/splunk/opentelemetry/profiler/LogExporterBuilder.java b/profiler/src/main/java/com/splunk/opentelemetry/profiler/LogExporterBuilder.java index b61cb1805..7afa8096f 100644 --- a/profiler/src/main/java/com/splunk/opentelemetry/profiler/LogExporterBuilder.java +++ b/profiler/src/main/java/com/splunk/opentelemetry/profiler/LogExporterBuilder.java @@ -47,10 +47,9 @@ static LogRecordExporter fromConfig(ConfigProperties config) { static LogRecordExporter buildGrpcExporter( ConfigProperties config, Supplier makeBuilder) { OtlpGrpcLogRecordExporterBuilder builder = makeBuilder.get(); - String ingestUrl = Configuration.getConfigUrl(config); - if (ingestUrl != null) { - builder.setEndpoint(ingestUrl); - } + String ingestUrl = Configuration.getIngestUrl(config); + builder.setEndpoint(ingestUrl); + return builder.addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE).build(); } @@ -58,7 +57,7 @@ static LogRecordExporter buildGrpcExporter( static LogRecordExporter buildHttpExporter( ConfigProperties config, Supplier makeBuilder) { OtlpHttpLogRecordExporterBuilder builder = makeBuilder.get(); - String ingestUrl = Configuration.getConfigUrl(config); + String ingestUrl = Configuration.getIngestUrl(config); OtlpConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, @@ -73,9 +72,8 @@ static LogRecordExporter buildHttpExporter( builder::setRetryPolicy, builder::setMemoryMode); - if (ingestUrl != null) { - builder.setEndpoint(ingestUrl); - } + builder.setEndpoint(ingestUrl); + return builder.addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE).build(); } } diff --git a/profiler/src/test/java/com/splunk/opentelemetry/profiler/ConfigurationTest.java b/profiler/src/test/java/com/splunk/opentelemetry/profiler/ConfigurationTest.java index b27fe4587..b4558b427 100644 --- a/profiler/src/test/java/com/splunk/opentelemetry/profiler/ConfigurationTest.java +++ b/profiler/src/test/java/com/splunk/opentelemetry/profiler/ConfigurationTest.java @@ -16,8 +16,10 @@ package com.splunk.opentelemetry.profiler; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -35,44 +37,89 @@ class ConfigurationTest { String logsEndpoint = "http://logs.example.com"; String otelEndpoint = "http://otel.example.com"; + String defaultLogsEndpoint = "http://localhost:4318/v1/logs"; @Test - void getConfigUrl_endpointDefined() { + void getIngestUrl_endpointDefined() { + // given ConfigProperties config = mock(ConfigProperties.class); - when(config.getString(Configuration.CONFIG_KEY_OTEL_OTLP_URL)).thenReturn(otelEndpoint); - when(config.getString(Configuration.CONFIG_KEY_INGEST_URL, otelEndpoint)) - .thenReturn(logsEndpoint); - String result = Configuration.getConfigUrl(config); - assertEquals(logsEndpoint, result); + when(config.getString(Configuration.CONFIG_KEY_INGEST_URL)).thenReturn(logsEndpoint); + + // when + String result = Configuration.getIngestUrl(config); + + // then + assertThat(result).isEqualTo(logsEndpoint); + } + + @Test + void getIngestUrl_endpointNotDefined_usedOtelGrpc() { + // given + ConfigProperties config = mock(ConfigProperties.class); + when(config.getString(Configuration.CONFIG_KEY_INGEST_URL)).thenReturn(null); + when(config.getString(eq(Configuration.CONFIG_KEY_OTEL_OTLP_URL), anyString())) + .thenReturn(otelEndpoint); + when(config.getString(eq(Configuration.CONFIG_KEY_PROFILER_OTLP_PROTOCOL), any())) + .thenReturn("grpc"); + + // when + String result = Configuration.getIngestUrl(config); + + // then + assertThat(result).isEqualTo(otelEndpoint); } @Test - void getConfigUrl_endpointNotDefined() { + void getIngestUrl_endpointNotDefined_usedOtelHttpProtobuf() { + // given ConfigProperties config = mock(ConfigProperties.class); - when(config.getString(Configuration.CONFIG_KEY_OTEL_OTLP_URL)).thenReturn(otelEndpoint); - when(config.getString(Configuration.CONFIG_KEY_INGEST_URL, otelEndpoint)) + when(config.getString(Configuration.CONFIG_KEY_INGEST_URL)).thenReturn(null); + when(config.getString(eq(Configuration.CONFIG_KEY_OTEL_OTLP_URL), anyString())) .thenReturn(otelEndpoint); - String result = Configuration.getConfigUrl(config); - assertEquals(otelEndpoint, result); + when(config.getString(eq(Configuration.CONFIG_KEY_PROFILER_OTLP_PROTOCOL), any())) + .thenReturn("http/protobuf"); + + // when + String result = Configuration.getIngestUrl(config); + + // then + assertThat(result).isEqualTo(otelEndpoint + "/v1/logs"); } @Test - void getConfigUrlNull() { + void getIngestUrl_endpointNotDefined_usedOtelHttpProtobufWithPath() { + // given + String endpoint = otelEndpoint + "/v1/logs"; + ConfigProperties config = mock(ConfigProperties.class); - when(config.getString(Configuration.CONFIG_KEY_OTEL_OTLP_URL, null)).thenReturn(null); - when(config.getString(Configuration.CONFIG_KEY_INGEST_URL, null)).thenReturn(null); - String result = Configuration.getConfigUrl(config); - assertNull(result); + when(config.getString(Configuration.CONFIG_KEY_INGEST_URL)).thenReturn(null); + when(config.getString(eq(Configuration.CONFIG_KEY_OTEL_OTLP_URL), anyString())) + .thenReturn(endpoint); + when(config.getString(eq(Configuration.CONFIG_KEY_PROFILER_OTLP_PROTOCOL), any())) + .thenReturn("http/protobuf"); + + // when + String result = Configuration.getIngestUrl(config); + + // then + assertThat(result).isEqualTo(endpoint); } @Test - void getConfigUrlSplunkRealm() { + void getIngestUrlSplunkRealm() { + // given ConfigProperties config = mock(ConfigProperties.class); - when(config.getString(Configuration.CONFIG_KEY_OTEL_OTLP_URL)) + when(config.getString(Configuration.CONFIG_KEY_INGEST_URL)).thenReturn(null); + when(config.getString(eq(Configuration.CONFIG_KEY_OTEL_OTLP_URL), anyString())) .thenReturn("https://ingest.us0.signalfx.com"); - when(config.getString(Configuration.CONFIG_KEY_INGEST_URL, null)).thenReturn(null); - String result = Configuration.getConfigUrl(config); - assertNull(result); + when(config.getString(eq(Configuration.CONFIG_KEY_PROFILER_OTLP_PROTOCOL), any())) + .thenReturn("http/protobuf"); + + // when + String result = Configuration.getIngestUrl(config); + + // then + assertThat(result).isEqualTo(defaultLogsEndpoint); } @Test @@ -80,7 +127,8 @@ void getOtlpProtocolDefault() { String result = Configuration.getOtlpProtocol( DefaultConfigProperties.create(Collections.emptyMap(), COMPONENT_LOADER)); - assertEquals("http/protobuf", result); + + assertThat(result).isEqualTo("http/protobuf"); } @Test @@ -89,16 +137,22 @@ void getOtlpProtocolOtelPropertySet() { Configuration.getOtlpProtocol( DefaultConfigProperties.create( Collections.singletonMap("otel.exporter.otlp.protocol", "test"), COMPONENT_LOADER)); - assertEquals("test", result); + + assertThat(result).isEqualTo("test"); } @Test void getOtlpProtocol() { + // given Map map = new HashMap<>(); map.put("otel.exporter.otlp.protocol", "test1"); map.put("splunk.profiler.otlp.protocol", "test2"); + + // when String result = Configuration.getOtlpProtocol(DefaultConfigProperties.create(map, COMPONENT_LOADER)); - assertEquals("test2", result); + + // then + assertThat(result).isEqualTo("test2"); } } diff --git a/profiler/src/test/java/com/splunk/opentelemetry/profiler/LogExporterBuilderTest.java b/profiler/src/test/java/com/splunk/opentelemetry/profiler/LogExporterBuilderTest.java index d9aadc474..22b20a0c9 100644 --- a/profiler/src/test/java/com/splunk/opentelemetry/profiler/LogExporterBuilderTest.java +++ b/profiler/src/test/java/com/splunk/opentelemetry/profiler/LogExporterBuilderTest.java @@ -18,10 +18,10 @@ import static com.splunk.opentelemetry.profiler.LogExporterBuilder.EXTRA_CONTENT_TYPE; import static com.splunk.opentelemetry.profiler.LogExporterBuilder.STACKTRACES_HEADER_VALUE; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -33,26 +33,51 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; class LogExporterBuilderTest { + static final String DEFAULT_HTTP_LOG_ENDPOINT = "http://localhost:4318/v1/logs"; + static final String DEFAULT_GRPC_LOG_ENDPOINT = "http://localhost:4317"; + + private MockedStatic configurationMock; + + @BeforeEach + void setUp() { + configurationMock = mockStatic(Configuration.class); + } + + @AfterEach + void tearDown() { + configurationMock.close(); + } @Test void testBuildSimpleGrpc() { + // given ConfigProperties config = mock(ConfigProperties.class); OtlpGrpcLogRecordExporterBuilder builder = mock(OtlpGrpcLogRecordExporterBuilder.class); OtlpGrpcLogRecordExporter expected = mock(OtlpGrpcLogRecordExporter.class); when(builder.addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE)).thenReturn(builder); when(builder.build()).thenReturn(expected); + configurationMock + .when(() -> Configuration.getIngestUrl(config)) + .thenReturn(DEFAULT_GRPC_LOG_ENDPOINT); + // when LogRecordExporter exporter = LogExporterBuilder.buildGrpcExporter(config, () -> builder); - assertSame(expected, exporter); - verify(builder, never()).setEndpoint(anyString()); + + // then + assertThat(exporter).isSameAs(expected); + verify(builder).setEndpoint(DEFAULT_GRPC_LOG_ENDPOINT); } @Test void testBuildSimpleHttp() { + // given ConfigProperties config = mock(ConfigProperties.class); OtlpHttpLogRecordExporterBuilder builder = mock(OtlpHttpLogRecordExporterBuilder.class); OtlpHttpLogRecordExporter expected = mock(OtlpHttpLogRecordExporter.class); @@ -60,14 +85,21 @@ void testBuildSimpleHttp() { when(builder.addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE)).thenReturn(builder); when(builder.build()).thenReturn(expected); when(config.getString("otel.exporter.otlp.protocol", "grpc")).thenReturn("http/protobuf"); + configurationMock + .when(() -> Configuration.getIngestUrl(config)) + .thenReturn(DEFAULT_HTTP_LOG_ENDPOINT); + // when LogRecordExporter exporter = LogExporterBuilder.buildHttpExporter(config, () -> builder); - assertSame(expected, exporter); - verify(builder, never()).setEndpoint(anyString()); + + // then + assertThat(exporter).isSameAs(expected); + verify(builder).setEndpoint(DEFAULT_HTTP_LOG_ENDPOINT); } @Test void extraOtlpHeaders() { + // given ConfigProperties config = mock(ConfigProperties.class); when(config.getMap("otel.exporter.otlp.headers")) .thenReturn(Map.of("foo", "bar", "bar", "baz")); @@ -80,8 +112,11 @@ void extraOtlpHeaders() { when(builder.addHeader(anyString(), anyString())).thenReturn(builder); when(builder.build()).thenReturn(expected); + // when LogRecordExporter exporter = LogExporterBuilder.buildHttpExporter(config, () -> builder); - assertSame(expected, exporter); + + // then + assertThat(exporter).isSameAs(expected); verify(builder).addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE); verify(builder).addHeader("log", "lady"); verify(builder, never()).addHeader("foo", "bar"); @@ -90,6 +125,7 @@ void extraOtlpHeaders() { @Test void extraOtlpLogSpecificHeaders() { + // given ConfigProperties config = mock(ConfigProperties.class); when(config.getMap("otel.exporter.otlp.headers")) .thenReturn(Map.of("foo", "bar", "bar", "baz")); @@ -101,56 +137,11 @@ void extraOtlpLogSpecificHeaders() { when(builder.addHeader(anyString(), anyString())).thenReturn(builder); when(builder.build()).thenReturn(expected); - LogRecordExporter exporter = LogExporterBuilder.buildHttpExporter(config, () -> builder); - assertSame(expected, exporter); - verify(builder).addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE); - } - - @Test - void testCustomEndpointGrpc() { - String endpoint = "http://example.com:9122/"; - - ConfigProperties config = mock(ConfigProperties.class); - OtlpGrpcLogRecordExporterBuilder builder = mock(OtlpGrpcLogRecordExporterBuilder.class); - OtlpGrpcLogRecordExporter expected = mock(OtlpGrpcLogRecordExporter.class); - - when(builder.addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE)).thenReturn(builder); - when(builder.build()).thenReturn(expected); - - when(config.getString(Configuration.CONFIG_KEY_PROFILER_OTLP_PROTOCOL, null)) - .thenReturn("grpc"); - when(config.getString(Configuration.CONFIG_KEY_OTEL_OTLP_URL)) - .thenReturn("http://shadowed.example.com:9122/"); - when(config.getString(Configuration.CONFIG_KEY_INGEST_URL, "http://shadowed.example.com:9122/")) - .thenReturn(endpoint); - LogRecordExporter exporter = LogExporterBuilder.buildGrpcExporter(config, () -> builder); - - assertNotNull(exporter); - verify(builder).setEndpoint(endpoint); - } - - @Test - void testCustomEndpointHttp() { - String endpoint = "http://example.com:9122/"; - - ConfigProperties config = mock(ConfigProperties.class); - OtlpHttpLogRecordExporterBuilder builder = mock(OtlpHttpLogRecordExporterBuilder.class); - OtlpHttpLogRecordExporter expected = mock(OtlpHttpLogRecordExporter.class); - - when(builder.addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE)).thenReturn(builder); - when(builder.build()).thenReturn(expected); - - when(config.getString(Configuration.CONFIG_KEY_PROFILER_OTLP_PROTOCOL, null)) - .thenReturn("http/protobuf"); - when(config.getString(Configuration.CONFIG_KEY_OTEL_OTLP_URL)) - .thenReturn("http://shadowed.example.com:9122/"); - when(config.getString( - Configuration.CONFIG_KEY_INGEST_URL, "http://shadowed.example.com:9122/v1/logs")) - .thenReturn(endpoint); - when(config.getString("otel.exporter.otlp.protocol", "grpc")).thenReturn("http/protobuf"); + // when LogRecordExporter exporter = LogExporterBuilder.buildHttpExporter(config, () -> builder); - assertNotNull(exporter); - verify(builder).setEndpoint(endpoint); + // then + assertThat(exporter).isSameAs(expected); + verify(builder).addHeader(EXTRA_CONTENT_TYPE, STACKTRACES_HEADER_VALUE); } }