Skip to content

feat: Introduce GRPC and unified export configuration with DSL#1562

Open
namanONcode wants to merge 3 commits intoopen-telemetry:mainfrom
namanONcode:issue-1507
Open

feat: Introduce GRPC and unified export configuration with DSL#1562
namanONcode wants to merge 3 commits intoopen-telemetry:mainfrom
namanONcode:issue-1507

Conversation

@namanONcode
Copy link
Copy Markdown
Contributor

This pull request introduces support for configuring OpenTelemetry export protocols (HTTP and gRPC) in a unified and flexible way. It adds new configuration classes, updates the initialization logic to select the appropriate exporter based on protocol, and enhances test coverage to verify all configuration paths.

Export protocol support and configuration:

  • Added ExportProtocol enum to represent supported export protocols (HTTP, GRPC).
  • Introduced new configuration classes: ExportConfiguration for unified protocol configuration and GrpcExportConfiguration for gRPC-specific settings. [1] [2]
  • Implemented GrpcEndpointConnectivity to encapsulate gRPC endpoint details.
  • Updated OpenTelemetryConfiguration to allow configuration via httpExport, grpcExport, or unified export DSLs, and store the selected configuration.

Initialization logic enhancements:

  • Refactored OpenTelemetryRumInitializer to resolve export endpoints and protocol based on the selected configuration, and dynamically create the correct exporters for spans, logs, and metrics (supporting both HTTP and gRPC). [1] [2] [3] [4]

Testing improvements:

  • Added comprehensive tests to verify initialization with all export configurations (HTTP, gRPC, unified export with HTTP/GRPC, and default). [1] [2] [3]
  • Added unit tests for the ExportProtocol enum to ensure correct behavior.…otocol selection.

@namanONcode namanONcode requested a review from a team as a code owner February 2, 2026 19:06
Copilot AI review requested due to automatic review settings February 2, 2026 19:06
@namanONcode namanONcode mentioned this pull request Feb 2, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request introduces comprehensive support for gRPC export protocol alongside the existing HTTP protocol in the OpenTelemetry Android agent. It provides three configuration approaches: protocol-specific DSLs (httpExport, grpcExport) and a unified export DSL that supports both protocols through a protocol parameter.

Changes:

  • Added ExportProtocol enum to distinguish between HTTP and GRPC protocols
  • Introduced GrpcExportConfiguration and ExportConfiguration classes for gRPC-specific and unified export configuration
  • Implemented GrpcEndpointConnectivity to handle gRPC endpoint details without path suffixes
  • Refactored initialization logic to dynamically select and instantiate appropriate exporters based on configured protocol

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
ExportProtocol.kt New enum defining HTTP and GRPC protocol options
GrpcEndpointConnectivity.kt New internal class implementing EndpointConnectivity for gRPC endpoints
GrpcExportConfiguration.kt New DSL configuration class for gRPC-specific export settings with signal overrides
ExportConfiguration.kt New unified DSL configuration supporting both HTTP and GRPC protocols
OpenTelemetryConfiguration.kt Added grpcExport() and export() DSL methods and internal config storage
OpenTelemetryRumInitializer.kt Refactored to resolve export endpoints based on configuration priority and create protocol-appropriate exporters
ExportProtocolTest.kt Unit tests for the ExportProtocol enum
GrpcEndpointConnectivityTest.kt Unit tests for GrpcEndpointConnectivity implementation
GrpcExportConfigurationTest.kt Comprehensive tests for gRPC export configuration DSL
ExportConfigurationTest.kt Comprehensive tests for unified export configuration DSL
OpenTelemetryConfigurationExportTest.kt Integration tests for all export configuration options
OpenTelemetryRumInitializerTest.kt Tests verifying initialization with various export configurations
Comments suppressed due to low confidence (1)

android-agent/src/main/kotlin/io/opentelemetry/android/agent/OpenTelemetryRumInitializer.kt:39

  • Important documentation was removed from the initialize function. The function should retain its KDoc comment explaining its purpose, parameters, and any important behavioral notes (such as the context parameter requirements regarding application context vs. activity context). This documentation is important for API consumers to understand how to use this public API correctly.
    @JvmStatic
    fun initialize(
        context: Context,
        configuration: (OpenTelemetryConfiguration.() -> Unit) = {},
    ): OpenTelemetryRum {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

internal val sessionConfig = SessionConfiguration()
internal val instrumentations = InstrumentationConfiguration(rumConfig)
internal var resourceAction: ResourceBuilder.() -> Unit = {}

Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation was removed for the httpExport function. This function should retain its KDoc comment to explain its purpose and usage, following the pattern established in the codebase (see the documentation in HttpExportConfiguration.kt for reference).

Suggested change
/**
* Configures exporting of telemetry over HTTP using [HttpExportConfiguration].
*/

Copilot uses AI. Check for mistakes.
fun grpcExport(action: GrpcExportConfiguration.() -> Unit) {
grpcExportConfig = GrpcExportConfiguration().apply(action)
}

Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing documentation for the export function. This new public API function should have KDoc documentation explaining its purpose, usage, and behavior. It should clarify that this is a unified export configuration DSL that supports both HTTP and gRPC protocols.

Suggested change
/**
* Configures export settings using a unified DSL that can target multiple protocols.
*
* This API is the preferred way to configure telemetry export and supports both HTTP
* and gRPC transports through a single [ExportConfiguration] entry point. It coexists
* with [httpExport] and [grpcExport], which provide protocol-specific configuration.
*
* The supplied [action] is applied to a new [ExportConfiguration] instance whose
* resulting state is stored and used when building the underlying exporters.
*/

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +55

fun spans(action: EndpointConfiguration.() -> Unit) {
spansConfig.action()
}

fun logs(action: EndpointConfiguration.() -> Unit) {
logsConfig.action()
}

Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing documentation for the spans, logs, and metrics functions. These public API functions should have KDoc documentation explaining their purpose, following the pattern established in HttpExportConfiguration (see HttpExportConfiguration.kt:60-79).

Suggested change
fun spans(action: EndpointConfiguration.() -> Unit) {
spansConfig.action()
}
fun logs(action: EndpointConfiguration.() -> Unit) {
logsConfig.action()
}
/**
* Configures export options specific to span data for this gRPC exporter.
*
* Values set in this configuration override the top-level [endpoint],
* [headers], and [compression] for span exports.
*
* @param action configuration block applied to the spans [EndpointConfiguration].
*/
fun spans(action: EndpointConfiguration.() -> Unit) {
spansConfig.action()
}
/**
* Configures export options specific to log data for this gRPC exporter.
*
* Values set in this configuration override the top-level [endpoint],
* [headers], and [compression] for log exports.
*
* @param action configuration block applied to the logs [EndpointConfiguration].
*/
fun logs(action: EndpointConfiguration.() -> Unit) {
logsConfig.action()
}
/**
* Configures export options specific to metric data for this gRPC exporter.
*
* Values set in this configuration override the top-level [endpoint],
* [headers], and [compression] for metric exports.
*
* @param action configuration block applied to the metrics [EndpointConfiguration].
*/

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +43
fun grpcExport(action: GrpcExportConfiguration.() -> Unit) {
grpcExportConfig = GrpcExportConfiguration().apply(action)
}

fun export(action: ExportConfiguration.() -> Unit) {
unifiedExportConfig = ExportConfiguration().apply(action)
}
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation allows multiple export configurations to coexist (httpExport, grpcExport, and export), but there's no clear documentation about the precedence order when multiple are set. Based on the resolveExportEndpoints logic (OpenTelemetryRumInitializer.kt:76-101), the precedence is: unified export > grpcExport > httpExport. Consider adding validation to warn users or prevent setting multiple export configurations, or at minimum, document this precedence clearly in the function documentation to avoid confusion.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +49

@Test
fun `HTTP ordinal is 0`() {
assertThat(ExportProtocol.HTTP.ordinal).isEqualTo(0)
}

@Test
fun `GRPC ordinal is 1`() {
assertThat(ExportProtocol.GRPC.ordinal).isEqualTo(1)
}
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests for enum ordinals (lines 42-49) are testing implementation details of Kotlin enums that are guaranteed by the language. The ordinal values depend on the declaration order and testing them creates a brittle test that will break if the enum values are reordered. Consider removing these tests as they don't provide meaningful value and can make refactoring unnecessarily difficult.

Suggested change
@Test
fun `HTTP ordinal is 0`() {
assertThat(ExportProtocol.HTTP.ordinal).isEqualTo(0)
}
@Test
fun `GRPC ordinal is 1`() {
assertThat(ExportProtocol.GRPC.ordinal).isEqualTo(1)
}

Copilot uses AI. Check for mistakes.
class GrpcExportConfiguration internal constructor() {
var endpoint: String = ""

var headers: Map<String, String> = emptyMap()
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The property name headers is inconsistent with the naming convention used in HttpExportConfiguration, which uses baseHeaders for the same purpose. For API consistency, consider renaming this property to baseHeaders to match the pattern established in HttpExportConfiguration (see HttpExportConfiguration.kt:24).

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +16
class GrpcExportConfiguration internal constructor() {
var endpoint: String = ""

var headers: Map<String, String> = emptyMap()

Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing property documentation for endpoint, headers, and compression. These public API properties should have KDoc documentation explaining their purpose and behavior, following the pattern established in HttpExportConfiguration (see HttpExportConfiguration.kt:16-28).

Suggested change
class GrpcExportConfiguration internal constructor() {
var endpoint: String = ""
var headers: Map<String, String> = emptyMap()
class GrpcExportConfiguration internal constructor() {
/**
* The base gRPC endpoint to which telemetry will be exported.
*
* This value is used for all signals (spans, logs, metrics) unless a
* signal-specific endpoint is configured via [spans], [logs], or [metrics].
*/
var endpoint: String = ""
/**
* Headers that will be sent with every gRPC export request.
*
* These headers are combined with any headers configured on the per-signal
* [EndpointConfiguration] instances used by [spans], [logs], and [metrics].
*/
var headers: Map<String, String> = emptyMap()
/**
* The compression algorithm to use for gRPC export requests.
*
* This acts as the default compression for all signals and may be overridden
* in the per-signal [EndpointConfiguration], if supported.
*/

Copilot uses AI. Check for mistakes.

import io.opentelemetry.android.agent.connectivity.Compression
import io.opentelemetry.android.agent.connectivity.GrpcEndpointConnectivity

Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing class-level documentation for GrpcExportConfiguration. This public API class should have KDoc documentation explaining its purpose, usage, and relationship to other export configuration classes, following the pattern established in HttpExportConfiguration (see HttpExportConfiguration.kt:11-13).

Suggested change
/**
* Configuration for exporting telemetry over gRPC from the Android agent DSL.
*
* This mirrors [HttpExportConfiguration] but targets gRPC exporters and is used from
* the `export { grpc { ... } }` section of the agent configuration DSL.
*
* Use [endpoint], [headers], and [compression] for common settings, and
* [spans], [logs], and [metrics] to override per-signal endpoints, headers,
* or compression as needed.
*/

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +21
class ExportConfiguration internal constructor() {
var protocol: ExportProtocol = ExportProtocol.HTTP

var endpoint: String = ""

var headers: Map<String, String> = emptyMap()

Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing property documentation for protocol, endpoint, headers, and compression. These public API properties should have KDoc documentation explaining their purpose and behavior, especially the protocol property which is key to this unified configuration approach.

Suggested change
class ExportConfiguration internal constructor() {
var protocol: ExportProtocol = ExportProtocol.HTTP
var endpoint: String = ""
var headers: Map<String, String> = emptyMap()
class ExportConfiguration internal constructor() {
/**
* Export protocol to use for all telemetry signals.
*
* This value controls whether HTTP or gRPC exporters are created in [spansEndpoint],
* [logsEndpoint], and [metricsEndpoint]. Per-signal configuration currently inherits
* this global protocol selection.
*/
var protocol: ExportProtocol = ExportProtocol.HTTP
/**
* Default endpoint URL used for all telemetry signals.
*
* Each signal (`spans`, `logs`, `metrics`) can define its own endpoint in
* [EndpointConfiguration]. If a signal-specific endpoint is blank, this global
* [endpoint] is used instead via [chooseEndpoint].
*/
var endpoint: String = ""
/**
* Global HTTP headers applied to all telemetry exports.
*
* These headers are merged with signal-specific headers configured via
* [EndpointConfiguration.headers]. When merging, entries from this global [headers]
* map override signal-specific headers that use the same key.
*/
var headers: Map<String, String> = emptyMap()
/**
* Default compression algorithm for all telemetry signals.
*
* A signal can override this by setting a non-null compression in its
* [EndpointConfiguration]. If no per-signal compression is provided, this global
* [compression] value is used by [chooseCompression].
*/

Copilot uses AI. Check for mistakes.
…corresponding configuration methods to OpenTelemetryConfiguration.
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 2, 2026

Codecov Report

❌ Patch coverage is 99.28571% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 67.04%. Comparing base (d5ff674) to head (485d278).
⚠️ Report is 118 commits behind head on main.

Files with missing lines Patch % Lines
...metry/android/agent/OpenTelemetryRumInitializer.kt 98.38% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1562      +/-   ##
==========================================
+ Coverage   64.45%   67.04%   +2.58%     
==========================================
  Files         160      161       +1     
  Lines        3182     3280      +98     
  Branches      326      332       +6     
==========================================
+ Hits         2051     2199     +148     
+ Misses       1030      984      -46     
+ Partials      101       97       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@breedx-splk
Copy link
Copy Markdown
Contributor

@namanONcode we expect that you are working on resolving the current comments from copilot before we undertake human reviews. Thanks.

@namanONcode
Copy link
Copy Markdown
Contributor Author

@namanONcode we expect that you are working on resolving the current comments from copilot before we undertake human reviews. Thanks.

@breedx-splk @fractalwrench please review any suggestions ?

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

android-agent/src/main/kotlin/io/opentelemetry/android/agent/OpenTelemetryRumInitializer.kt:39

  • The public initialize function’s KDoc was removed. This method is a primary entry point for the library and the docs contained important guidance about requiring an Application context (and the attachBaseContext caveat). Consider re-adding that documentation (even if the implementation remains unchanged) to avoid accidental misuse by callers.
    @JvmStatic
    fun initialize(
        context: Context,
        configuration: (OpenTelemetryConfiguration.() -> Unit) = {},
    ): OpenTelemetryRum {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 21 to 25
class OpenTelemetryConfiguration internal constructor(
internal val rumConfig: OtelRumConfig = OtelRumConfig(),
internal val diskBufferingConfig: DiskBufferingConfigurationSpec = DiskBufferingConfigurationSpec(rumConfig),
/**
* Configures the [Clock] used for capturing telemetry.
*/
var clock: Clock = OtelAndroidClock(),
) {
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The KDoc describing the purpose of the clock configuration option was removed. Since clock is a user-configurable input that affects timestamps and session behavior, restoring the brief documentation here would help API consumers understand when/why they might override it (e.g., for tests).

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +35
* Each signal ([spans], [logs], [metrics]) can define its own endpoint.
* If a signal-specific endpoint is blank, this global endpoint is used instead.
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ExportConfiguration.endpoint is documented as a generic “endpoint URL”, but its meaning differs by protocol (HTTP uses it as a base URL to which /v1/{signal} is appended; gRPC uses it as the final endpoint passed to the gRPC exporter). Updating the property KDoc to spell out this protocol-dependent behavior would prevent misconfiguration (e.g., users providing a full /v1/traces URL when protocol=HTTP and getting a doubled path).

Suggested change
* Each signal ([spans], [logs], [metrics]) can define its own endpoint.
* If a signal-specific endpoint is blank, this global endpoint is used instead.
* How this value is interpreted depends on [protocol]:
* - When [ExportProtocol.HTTP] is used, this is treated as the base URL to which the
* signal-specific REST path (for example, `/v1/traces`, `/v1/logs`, `/v1/metrics`) is
* appended by the HTTP exporters. In this case, do not include the `/v1/{signal}` suffix
* in this value to avoid a doubled path.
* - When [ExportProtocol.GRPC] is used, this is passed directly to the gRPC exporter as the
* full endpoint (including any required path or port).
*
* Each signal ([spans], [logs], [metrics]) can define its own endpoint via
* [EndpointConfiguration.url]. If a signal-specific endpoint is blank, this global endpoint
* is used instead, following the same protocol-dependent behavior described above.

Copilot uses AI. Check for mistakes.
@namanONcode
Copy link
Copy Markdown
Contributor Author

@breedx-splk all review has been resolved please go through for human suggestions ?

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.

Comments suppressed due to low confidence (1)

android-agent/src/main/kotlin/io/opentelemetry/android/agent/OpenTelemetryRumInitializer.kt:39

  • The KDoc for initialize (explaining required application context and configuration behavior) was removed. Since this is a public entry point, please keep/restore the API documentation so callers understand context requirements and the DSL parameter semantics.
object OpenTelemetryRumInitializer {
    @JvmStatic
    fun initialize(
        context: Context,
        configuration: (OpenTelemetryConfiguration.() -> Unit) = {},
    ): OpenTelemetryRum {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +100 to +104
HttpEndpointConnectivity.forMetrics(
chooseEndpoint(metricsConfig),
metricsConfig.headers + headers,
chooseCompression(metricsConfig.compression),
)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In metricsEndpoint(), metricsConfig.headers + headers makes global headers win on duplicate keys, which is the opposite of the stated override semantics in the method KDoc. Consider swapping the operands (or updating docs/tests) so per-signal headers can override global ones.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +64
spansConfig.headers + headers,
chooseCompression(spansConfig.compression),
)

internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
logsConfig.headers + headers,
chooseCompression(logsConfig.compression),
)

internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
metricsConfig.headers + headers,
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In spansEndpoint(), headers are merged as spansConfig.headers + headers, which means the top-level headers override per-signal headers on key conflicts (right-hand side wins for Kotlin map +). This conflicts with the KDoc stating per-signal values override; consider reversing the merge order or updating the KDoc to reflect actual behavior.

Suggested change
spansConfig.headers + headers,
chooseCompression(spansConfig.compression),
)
internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
logsConfig.headers + headers,
chooseCompression(logsConfig.compression),
)
internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
metricsConfig.headers + headers,
headers + spansConfig.headers,
chooseCompression(spansConfig.compression),
)
internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
headers + logsConfig.headers,
chooseCompression(logsConfig.compression),
)
internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
headers + metricsConfig.headers,

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +64
spansConfig.headers + headers,
chooseCompression(spansConfig.compression),
)

internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
logsConfig.headers + headers,
chooseCompression(logsConfig.compression),
)

internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
metricsConfig.headers + headers,
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In logsEndpoint(), the current merge order logsConfig.headers + headers makes global headers take precedence over per-signal headers for duplicate keys. If per-signal overrides are intended, swap the merge order (or adjust documentation accordingly).

Suggested change
spansConfig.headers + headers,
chooseCompression(spansConfig.compression),
)
internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
logsConfig.headers + headers,
chooseCompression(logsConfig.compression),
)
internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
metricsConfig.headers + headers,
headers + spansConfig.headers,
chooseCompression(spansConfig.compression),
)
internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
headers + logsConfig.headers,
chooseCompression(logsConfig.compression),
)
internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
headers + metricsConfig.headers,

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +64
spansConfig.headers + headers,
chooseCompression(spansConfig.compression),
)

internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
logsConfig.headers + headers,
chooseCompression(logsConfig.compression),
)

internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
metricsConfig.headers + headers,
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In metricsEndpoint(), metricsConfig.headers + headers causes global headers to override per-signal headers on key collision, which is inconsistent with the documented override behavior. Consider reversing the merge order or updating docs/tests to match precedence.

Suggested change
spansConfig.headers + headers,
chooseCompression(spansConfig.compression),
)
internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
logsConfig.headers + headers,
chooseCompression(logsConfig.compression),
)
internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
metricsConfig.headers + headers,
headers + spansConfig.headers,
chooseCompression(spansConfig.compression),
)
internal fun logsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(logsConfig),
headers + logsConfig.headers,
chooseCompression(logsConfig.compression),
)
internal fun metricsEndpoint(): GrpcEndpointConnectivity =
GrpcEndpointConnectivity.create(
chooseEndpoint(metricsConfig),
headers + metricsConfig.headers,

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +28
fun testHttpExportDefaultConfig() {
assertNotNull(config.exportConfig)
assertEquals("", config.exportConfig.baseUrl)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exportConfig is a non-null val on OpenTelemetryConfiguration, so assertNotNull(config.exportConfig) is redundant. Consider removing it to keep the test focused on meaningful behavior assertions.

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +66
HttpEndpointConnectivity.forTraces(
chooseEndpoint(spansConfig),
spansConfig.headers + headers,
chooseCompression(spansConfig.compression),
)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In spansEndpoint(), headers are merged as spansConfig.headers + headers. With Kotlin map +, keys from the right-hand map win, so global headers override per-signal headers on key conflicts. This contradicts the KDoc that says signal-specific values override top-level settings; consider reversing the merge order (global first, then signal) or updating the documentation/expectations accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +85
HttpEndpointConnectivity.forLogs(
chooseEndpoint(logsConfig),
logsConfig.headers + headers,
chooseCompression(logsConfig.compression),
)
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In logsEndpoint(), the merge order logsConfig.headers + headers causes global headers to override per-signal headers when keys collide. If per-signal configuration is intended to override, reverse the merge order or adjust the docs to match the implemented precedence.

Copilot uses AI. Check for mistakes.
@fractalwrench
Copy link
Copy Markdown
Member

@namanONcode there are 2 blockers to start reviewing this from my POV:

  1. There are still several unresolved review comments from AI
  2. The PR is large. I don't review any PR with a diff that is more than ~500 lines as a general rule

Once you resolve those two blockers then I'll find time to review contributions.

@breedx-splk
Copy link
Copy Markdown
Contributor

@namanONcode we need you to circle back on this and address the things that @fractalwrench mentioned above, as well as resolving the large number of ai review comments and the merge conflict. Thanks!

@breedx-splk breedx-splk added the needs author feedback Waiting for additional feedback from the author label Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs author feedback Waiting for additional feedback from the author now-with-even-more-AI-than-ever

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants