Skip to content

Commit dcb7c4a

Browse files
author
Emmanuela Opurum
committed
feat: support fullUrl in EndpointConfiguration to bypass default signal path
Signed-off-by: Emmanuela Opurum <youremail@example.com>
1 parent a18074b commit dcb7c4a

4 files changed

Lines changed: 125 additions & 18 deletions

File tree

android-agent/src/main/kotlin/io/opentelemetry/android/agent/connectivity/HttpEndpointConnectivity.kt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright The OpenTelemetry Authors
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
65
package io.opentelemetry.android.agent.connectivity
76

87
internal class HttpEndpointConnectivity private constructor(
@@ -15,12 +14,13 @@ internal class HttpEndpointConnectivity private constructor(
1514
companion object {
1615
fun forTraces(
1716
baseUrl: String,
17+
fullUrl: Boolean = false,
1818
headers: Map<String, String>,
1919
compression: Compression,
2020
sslContext: SSLContextConnectivity?,
2121
clientTls: ClientTlsConnectivity?
2222
): HttpEndpointConnectivity = HttpEndpointConnectivity(
23-
baseUrl.trimEnd('/') + "/v1/traces",
23+
if (fullUrl) baseUrl else baseUrl.trimEnd('/') + "/v1/traces",
2424
headers,
2525
compression,
2626
sslContext,
@@ -29,12 +29,13 @@ internal class HttpEndpointConnectivity private constructor(
2929

3030
fun forLogs(
3131
baseUrl: String,
32+
fullUrl: Boolean = false,
3233
headers: Map<String, String>,
3334
compression: Compression,
3435
sslContext: SSLContextConnectivity?,
3536
clientTls: ClientTlsConnectivity?
3637
): HttpEndpointConnectivity = HttpEndpointConnectivity(
37-
baseUrl.trimEnd('/') + "/v1/logs",
38+
if (fullUrl) baseUrl else baseUrl.trimEnd('/') + "/v1/logs",
3839
headers,
3940
compression,
4041
sslContext,
@@ -43,12 +44,13 @@ internal class HttpEndpointConnectivity private constructor(
4344

4445
fun forMetrics(
4546
baseUrl: String,
47+
fullUrl: Boolean = false,
4648
headers: Map<String, String>,
4749
compression: Compression,
4850
sslContext: SSLContextConnectivity?,
4951
clientTls: ClientTlsConnectivity?
5052
): HttpEndpointConnectivity = HttpEndpointConnectivity(
51-
baseUrl.trimEnd('/') + "/v1/metrics",
53+
if (fullUrl) baseUrl else baseUrl.trimEnd('/') + "/v1/metrics",
5254
headers,
5355
compression,
5456
sslContext,
@@ -57,12 +59,8 @@ internal class HttpEndpointConnectivity private constructor(
5759
}
5860

5961
override fun getUrl(): String = url
60-
6162
override fun getHeaders(): Map<String, String> = headers
62-
6363
override fun getCompression(): Compression = compression
64-
6564
override fun getSslContext(): SSLContextConnectivity? = sslContext
66-
6765
override fun getClientTls(): ClientTlsConnectivity? = clientTls
68-
}
66+
}

android-agent/src/main/kotlin/io/opentelemetry/android/agent/dsl/EndpointConfiguration.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright The OpenTelemetry Authors
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
65
package io.opentelemetry.android.agent.dsl
76

87
import io.opentelemetry.android.agent.connectivity.Compression
@@ -13,9 +12,16 @@ import io.opentelemetry.android.agent.connectivity.Compression
1312
@OpenTelemetryDslMarker
1413
class EndpointConfiguration internal constructor(
1514
/**
16-
* URL for HTTP export requests.
15+
* Base URL for HTTP export requests. The signal-specific path (e.g. /v1/logs) will be
16+
* appended automatically.
1717
*/
1818
var url: String,
19+
/**
20+
* Full URL for HTTP export requests. When set, this URL is used as-is without appending
21+
* any signal-specific path. Use this to specify a completely custom endpoint path,
22+
* for example "https://example.com/v2/logs".
23+
*/
24+
var fullUrl: String? = null,
1925
/**
2026
* Headers that should be attached to HTTP export requests.
2127
*/
@@ -24,4 +30,4 @@ class EndpointConfiguration internal constructor(
2430
* Compression algorithm.
2531
*/
2632
var compression: Compression? = null,
27-
)
33+
)

android-agent/src/main/kotlin/io/opentelemetry/android/agent/dsl/HttpExportConfiguration.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright The OpenTelemetry Authors
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
65
package io.opentelemetry.android.agent.dsl
76

87
import io.opentelemetry.android.Incubating
@@ -50,31 +49,36 @@ class HttpExportConfiguration internal constructor() {
5049
internal fun spansEndpoint(): HttpEndpointConnectivity =
5150
HttpEndpointConnectivity.forTraces(
5251
chooseUrlSource(spansConfig),
52+
isFullUrl(spansConfig),
5353
spansConfig.headers + baseHeaders,
5454
chooseCompression(spansConfig.compression),
5555
sslContext,
56-
clientTls
56+
clientTls,
5757
)
5858

5959
internal fun logsEndpoint(): HttpEndpointConnectivity =
6060
HttpEndpointConnectivity.forLogs(
6161
chooseUrlSource(logsConfig),
62+
isFullUrl(logsConfig),
6263
logsConfig.headers + baseHeaders,
6364
chooseCompression(logsConfig.compression),
6465
sslContext,
65-
clientTls
66+
clientTls,
6667
)
6768

6869
internal fun metricsEndpoint(): HttpEndpointConnectivity =
6970
HttpEndpointConnectivity.forMetrics(
7071
chooseUrlSource(metricsConfig),
72+
isFullUrl(metricsConfig),
7173
metricsConfig.headers + baseHeaders,
7274
chooseCompression(metricsConfig.compression),
7375
sslContext,
74-
clientTls
76+
clientTls,
7577
)
7678

77-
private fun chooseUrlSource(cfg: EndpointConfiguration): String = cfg.url.ifBlank { baseUrl }
79+
private fun chooseUrlSource(cfg: EndpointConfiguration): String = cfg.fullUrl ?: cfg.url.ifBlank { baseUrl }
80+
81+
private fun isFullUrl(cfg: EndpointConfiguration): Boolean = cfg.fullUrl != null
7882

7983
private fun chooseCompression(signalConfigCompression: Compression?): Compression = signalConfigCompression ?: this.compression
8084

@@ -98,4 +102,4 @@ class HttpExportConfiguration internal constructor() {
98102
fun metrics(action: EndpointConfiguration.() -> Unit) {
99103
metricsConfig.action()
100104
}
101-
}
105+
}

android-agent/src/test/kotlin/io/opentelemetry/android/agent/dsl/HttpExportConfigurationTest.kt

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,103 @@ internal class HttpExportConfigurationTest {
316316
return ClientTlsConnectivity(privateKeyPem, certificatePem)
317317
}
318318

319+
@Test
320+
fun testFullUrlOverrideForLogs() {
321+
val baseUrl = "http://localhost:4318/"
322+
val customLogsUrl = "http://localhost:4318/v2/logs"
323+
324+
val config =
325+
otelConfig.exportConfig.apply {
326+
this.baseUrl = baseUrl
327+
logs {
328+
fullUrl = customLogsUrl
329+
}
330+
}
331+
332+
// logs should use the full custom URL without appending /v1/logs
333+
config.logsEndpoint().assertEndpointConfig(
334+
customLogsUrl,
335+
emptyMap(),
336+
Compression.GZIP,
337+
null
338+
)
339+
// spans and metrics should still use baseUrl + default path
340+
config.spansEndpoint().assertEndpointConfig(
341+
"${baseUrl}v1/traces",
342+
emptyMap(),
343+
Compression.GZIP,
344+
null
345+
)
346+
config.metricsEndpoint().assertEndpointConfig(
347+
"${baseUrl}v1/metrics",
348+
emptyMap(),
349+
Compression.GZIP,
350+
null
351+
)
352+
}
353+
354+
@Test
355+
fun testFullUrlOverrideForAllSignals() {
356+
val customSpansUrl = "http://traces.example.com/v2/traces"
357+
val customLogsUrl = "http://logs.example.com/v2/logs"
358+
val customMetricsUrl = "http://metrics.example.com/v2/metrics"
359+
360+
val config =
361+
otelConfig.exportConfig.apply {
362+
spans {
363+
fullUrl = customSpansUrl
364+
}
365+
logs {
366+
fullUrl = customLogsUrl
367+
}
368+
metrics {
369+
fullUrl = customMetricsUrl
370+
}
371+
}
372+
373+
config.spansEndpoint().assertEndpointConfig(
374+
customSpansUrl,
375+
emptyMap(),
376+
Compression.GZIP,
377+
null
378+
)
379+
config.logsEndpoint().assertEndpointConfig(
380+
customLogsUrl,
381+
emptyMap(),
382+
Compression.GZIP,
383+
null
384+
)
385+
config.metricsEndpoint().assertEndpointConfig(
386+
customMetricsUrl,
387+
emptyMap(),
388+
Compression.GZIP,
389+
null
390+
)
391+
}
392+
393+
@Test
394+
fun testFullUrlTakesPrecedenceOverUrl() {
395+
val baseUrl = "http://localhost:4318/"
396+
val signalUrl = "http://localhost:4318/logs/"
397+
val customFullUrl = "http://localhost:4318/v2/logs"
398+
399+
val config =
400+
otelConfig.exportConfig.apply {
401+
this.baseUrl = baseUrl
402+
logs {
403+
url = signalUrl
404+
fullUrl = customFullUrl
405+
}
406+
}
407+
408+
// fullUrl should take precedence over url
409+
config.logsEndpoint().assertEndpointConfig(
410+
customFullUrl,
411+
emptyMap(),
412+
Compression.GZIP,
413+
null
414+
)
415+
}
416+
417+
319418
}

0 commit comments

Comments
 (0)