Open Telemetry Integration

Surge integrates with Open Telemetry compatible platforms such as Jaeger, Zipkin, Honeycomb etc.

Example Configuration

You can provide an OpenTelemetry instance by overriding openTelemetry in your Surge model.

Using Honeycomb

sbt
libraryDependencies ++= Seq(
  "io.opentelemetry" % "opentelemetry-sdk" % "1.4.1",
  "io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.4.1",
  "io.grpc" % "grpc-netty-shaded" % "1.39.0"
)
Maven
<dependencies>
  <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk</artifactId>
    <version>1.4.1</version>
  </dependency>
  <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-otlp</artifactId>
    <version>1.4.1</version>
  </dependency>
  <dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-netty-shaded</artifactId>
    <version>1.39.0</version>
  </dependency>
</dependencies>
Gradle
dependencies {
  implementation "io.opentelemetry:opentelemetry-sdk:1.4.1"
  implementation "io.opentelemetry:opentelemetry-exporter-otlp:1.4.1"
  implementation "io.grpc:grpc-netty-shaded:1.39.0"
}
Scala
source// format: off
object BankAccountSurgeModelWithHoneycomb
  extends SurgeCommandBusinessLogic[UUID, BankAccount, BankAccountCommand, BankAccountEvent] {

  import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
  import io.opentelemetry.context.propagation.ContextPropagators
  import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter
  import io.opentelemetry.sdk.OpenTelemetrySdk
  import io.opentelemetry.sdk.trace.SdkTracerProvider
  import io.opentelemetry.sdk.trace.`export`.BatchSpanProcessor

  override val openTelemetry = {

    val sdkTracerProvider = SdkTracerProvider.builder()
      .addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
        .setEndpoint("https://api.honeycomb.io")
        .addHeader("x-honeycomb-dataset", "data-set-name")
        .addHeader("x-honeycomb-team", "YOUR_API_KEY").build()).build())
      .setResource(Resource.builder().put("service.name", "bank").build())
      .build()

    val openTelemetry: OpenTelemetrySdk = OpenTelemetrySdk.builder()
      .setTracerProvider(sdkTracerProvider)
      .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
      .buildAndRegisterGlobal()

    openTelemetry
  }



  override def commandModel: AggregateCommandModel[BankAccount, BankAccountCommand, BankAccountEvent]
   = BankAccountCommandModel

  override def aggregateName: String = "bank-account"

  override def stateTopic: KafkaTopic = KafkaTopic("bank-account-state")

  override def eventsTopic: KafkaTopic = KafkaTopic("bank-account-events")

  override def aggregateReadFormatting: SurgeAggregateReadFormatting[BankAccount] = ???

  override def aggregateWriteFormatting: SurgeAggregateWriteFormatting[BankAccount] = ???

  override def eventWriteFormatting: SurgeEventWriteFormatting[BankAccountEvent] = ???

}
Java
Java examples coming soon..

Screenshot (Honeycomb)

Honeycomb Screenshot

Using Jaeger

sbt
libraryDependencies ++= Seq(
  "io.opentelemetry" % "opentelemetry-sdk" % "1.4.1",
  "io.opentelemetry" % "opentelemetry-exporter-jaeger" % "1.4.1",
  "io.grpc" % "grpc-netty-shaded" % "1.39.0"
)
Maven
<dependencies>
  <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk</artifactId>
    <version>1.4.1</version>
  </dependency>
  <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-jaeger</artifactId>
    <version>1.4.1</version>
  </dependency>
  <dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-netty-shaded</artifactId>
    <version>1.39.0</version>
  </dependency>
</dependencies>
Gradle
dependencies {
  implementation "io.opentelemetry:opentelemetry-sdk:1.4.1"
  implementation "io.opentelemetry:opentelemetry-exporter-jaeger:1.4.1"
  implementation "io.grpc:grpc-netty-shaded:1.39.0"
}
Scala
source// format: off
object BankAccountSurgeModelWithJaeger
  extends SurgeCommandBusinessLogic[UUID, BankAccount, BankAccountCommand, BankAccountEvent] {

  import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
  import io.opentelemetry.context.propagation.ContextPropagators
  import io.opentelemetry.sdk.OpenTelemetrySdk
  import io.opentelemetry.sdk.trace.SdkTracerProvider
  import io.opentelemetry.sdk.trace.`export`.BatchSpanProcessor

  override val openTelemetry = {

    val exporter =
      JaegerGrpcSpanExporter.builder()
        .setEndpoint("http://localhost:14250")
        .build()

    val sdkTracerProvider = SdkTracerProvider.builder()
      .addSpanProcessor(BatchSpanProcessor.builder(exporter).build())
      .setResource(Resource.builder().put("service.name", "bank").build())
      .build()

    val openTelemetry: OpenTelemetrySdk = OpenTelemetrySdk.builder()
      .setTracerProvider(sdkTracerProvider)
      .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
      .buildAndRegisterGlobal()

    openTelemetry
  }



  override def commandModel: AggregateCommandModel[BankAccount, BankAccountCommand, BankAccountEvent]
   = BankAccountCommandModel

  override def aggregateName: String = "bank-account"

  override def stateTopic: KafkaTopic = KafkaTopic("bank-account-state")

  override def eventsTopic: KafkaTopic = KafkaTopic("bank-account-events")

  override def aggregateReadFormatting: SurgeAggregateReadFormatting[BankAccount] = ???

  override def aggregateWriteFormatting: SurgeAggregateWriteFormatting[BankAccount] = ???

  override def eventWriteFormatting: SurgeEventWriteFormatting[BankAccountEvent] = ???

}
Java
Java examples coming soon..

Screenshot (Jaeger)

Jaeger Screenshot

The source code for this page can be found here.