diff --git a/reporters/kamon-opentelemetry/src/main/resources/reference.conf b/reporters/kamon-opentelemetry/src/main/resources/reference.conf index 0d9a3c31b..922f85db6 100644 --- a/reporters/kamon-opentelemetry/src/main/resources/reference.conf +++ b/reporters/kamon-opentelemetry/src/main/resources/reference.conf @@ -27,6 +27,9 @@ kamon.otel { attributes = "" attributes = ${?OTEL_RESOURCE_ATTRIBUTES} + retryEnabled = false + retryEnabled = ${?OTEL_EXPERIMENTAL_EXPORTER_OTLP_RETRY_ENABLED} + trace { endpoint = ${kamon.otel.endpoint} full-endpoint = ${?OTEL_EXPORTER_OTLP_TRACES_ENDPOINT} @@ -43,6 +46,7 @@ kamon.otel { protocol = ${kamon.otel.protocol} protocol = ${?OTEL_EXPORTER_OTLP_TRACES_PROTOCOL} + retryEnabled = ${kamon.otel.retryEnabled} # If set to true, any error (message and stacktrace) on a span will be included as an event on the span with # standard attribute names; enable for 'more full' compliance with otel standard include-error-event = false diff --git a/reporters/kamon-opentelemetry/src/main/scala/kamon/otel/TraceService.scala b/reporters/kamon-opentelemetry/src/main/scala/kamon/otel/TraceService.scala index 1909b5619..f7b923af2 100644 --- a/reporters/kamon-opentelemetry/src/main/scala/kamon/otel/TraceService.scala +++ b/reporters/kamon-opentelemetry/src/main/scala/kamon/otel/TraceService.scala @@ -23,6 +23,7 @@ import java.util.{Collection => JCollection} import scala.concurrent.{Future, Promise} import com.typesafe.config.Config +import io.opentelemetry.exporter.internal.retry.{RetryPolicy, RetryUtil} import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter import io.opentelemetry.sdk.trace.`export`.SpanExporter @@ -71,6 +72,7 @@ private[otel] object OtlpTraceService { case Array(k, v) => k -> v }.toSeq val timeout = otelExporterConfig.getDuration("timeout") + val retryEnabled = otelExporterConfig.getBoolean("retryEnabled") // See https://opentelemetry.io/docs/reference/specification/protocol/exporter/#endpoint-urls-for-otlphttp val url = (protocol, fullEndpoint) match { case ("http/protobuf", Some(full)) => @@ -85,20 +87,22 @@ private[otel] object OtlpTraceService { logger.info(s"Configured endpoint for OpenTelemetry trace reporting [$url] using $protocol protocol") - new OtlpTraceService(protocol, url, compression, headers, timeout) + new OtlpTraceService(protocol, url, compression, headers, timeout, retryEnabled) } } -private[otel] class OtlpTraceService(protocol: String, endpoint: String, compressionEnabled: Boolean, headers: Seq[(String, String)], timeout: Duration) extends TraceService { +private[otel] class OtlpTraceService(protocol: String, endpoint: String, compressionEnabled: Boolean, headers: Seq[(String, String)], timeout: Duration, retryEnabled: Boolean) extends TraceService { private val compressionMethod = if (compressionEnabled) "gzip" else "none" private val delegate: SpanExporter = protocol match { case "grpc" => val builder = OtlpGrpcSpanExporter.builder().setEndpoint(endpoint).setCompression(compressionMethod).setTimeout(timeout) headers.foreach { case (k, v) => builder.addHeader(k, v) } + if (retryEnabled) RetryUtil.setRetryPolicyOnDelegate(builder, RetryPolicy.getDefault) builder.build() case "http/protobuf" => val builder = OtlpHttpSpanExporter.builder().setEndpoint(endpoint).setCompression(compressionMethod).setTimeout(timeout) headers.foreach { case (k, v) => builder.addHeader(k, v) } + if (retryEnabled) RetryUtil.setRetryPolicyOnDelegate(builder, RetryPolicy.getDefault) builder.build() }