Skip to content

Commit

Permalink
inline AwsXrayIdGenerator from io.opentelemetry.contrib:opentelemetry…
Browse files Browse the repository at this point in the history
…-aws-xray to minimize transitive dependencies
  • Loading branch information
bpholt committed Mar 8, 2024
1 parent 29384c5 commit 0c736cd
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 19 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ jobs:

- name: Make target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
run: mkdir -p core/target project/target
run: mkdir -p aws-xray-id-generator/target core/target project/target

- name: Compress target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
run: tar cf targets.tar core/target project/target
run: tar cf targets.tar aws-xray-id-generator/target core/target project/target

- name: Upload target directories
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
Expand Down
8 changes: 8 additions & 0 deletions .mergify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ pull_request_rules:
- status-success=Build and Test (ubuntu-latest, 2.12, temurin@17, rootJVM)
actions:
merge: {}
- name: Label aws-xray-id-generator PRs
conditions:
- files~=^aws-xray-id-generator/
actions:
label:
add:
- aws-xray-id-generator
remove: []
- name: Label core PRs
conditions:
- files~=^core/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2024 Dwolla, Inc
* SPDX-License-Identifier: Apache-2.0
* Based on https://github.com/open-telemetry/opentelemetry-java-contrib/blob/eece7e8ef04170fb463ddf692f61d4527b50febf/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayIdGenerator.java
*/
package com.dwolla.tracing

import cats.effect.*
import cats.effect.std.*
import cats.*
import cats.syntax.all.*
import io.opentelemetry.api.trace.{SpanId, TraceId}
import io.opentelemetry.sdk.trace.IdGenerator

object AwsXrayIdGenerator {
def apply[F[_] : Applicative : Clock : Random](dispatcher: Dispatcher[F]): AwsXrayIdGenerator[F] =
new AwsXrayIdGenerator(dispatcher)
}

class AwsXrayIdGenerator[F[_] : Applicative : Clock : Random](dispatcher: Dispatcher[F]) extends IdGenerator {
override def generateSpanId(): String =
dispatcher.unsafeRunSync {
Random[F]
.nextLong
.map(SpanId.fromLong)
}

override def generateTraceId(): String = dispatcher.unsafeRunSync {
(Clock[F].realTime.map(_.toSeconds),
Random[F].nextInt.map(_ & 0xFFFFFFFFL),
Random[F].nextLong
).mapN { case (timestampSecs, hiRandom, lowRandom) =>
TraceId.fromLongs(timestampSecs << 32 | hiRandom, lowRandom)
}
}
}
21 changes: 18 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// https://typelevel.org/sbt-typelevel/faq.html#what-is-a-base-version-anyway
ThisBuild / tlBaseVersion := "0.2"
ThisBuild / tlBaseVersion := "0.3"

ThisBuild / organization := "com.dwolla"
ThisBuild / organizationName := "Dwolla"
Expand All @@ -24,7 +24,10 @@ ThisBuild / mergifyStewardConfig ~= { _.map(_.copy(
mergeMinors = true,
))}

lazy val root = tlCrossRootProject.aggregate(core)
lazy val root = tlCrossRootProject.aggregate(
core,
`aws-xray-id-generator`,
)

lazy val core = project.in(file("core"))
.settings(
Expand All @@ -51,6 +54,18 @@ lazy val core = project.in(file("core"))
"io.opentelemetry.semconv" % "opentelemetry-semconv" % "1.23.1-alpha",
"io.opentelemetry.contrib" % "opentelemetry-aws-resources" % "1.32.0-alpha",
"io.opentelemetry.contrib" % "opentelemetry-aws-xray-propagator" % "1.32.0-alpha",
"io.opentelemetry.contrib" % "opentelemetry-aws-xray" % "1.32.0",
)
)
.dependsOn(`aws-xray-id-generator`)

lazy val `aws-xray-id-generator` = project
.in(file("aws-xray-id-generator"))
.settings(
name := "otel-aws-xray-id-generator",
description := "Generate OTel trace IDs compatible with AWS X-Ray with minimal dependencies",
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-effect" % "3.5.2",
"io.opentelemetry" % "opentelemetry-api" % "1.33.0",
"io.opentelemetry" % "opentelemetry-sdk-trace" % "1.33.0",
)
)
28 changes: 14 additions & 14 deletions core/src/main/scala/com/dwolla/tracing/OpenTelemetryAtDwolla.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import io.opentelemetry.api.common.Attributes
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
import io.opentelemetry.context.propagation.{ContextPropagators, TextMapPropagator}
import io.opentelemetry.contrib.aws.resource.{Ec2Resource, EcsResource}
import io.opentelemetry.contrib.awsxray.AwsXrayIdGenerator
import io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter
import io.opentelemetry.extension.trace.propagation.B3Propagator
Expand All @@ -21,30 +20,31 @@ import natchez.opentelemetry.OpenTelemetry
import org.typelevel.log4cats.LoggerFactory

object OpenTelemetryAtDwolla {
def apply[F[_] : Sync : Env](serviceName: String,
env: DwollaEnvironment): Resource[F, EntryPoint[F]] =
buildOtel(serviceName, env, None)

def apply[F[_] : Async : Env : LoggerFactory](serviceName: String,
env: DwollaEnvironment,
logTraces: Boolean): Resource[F, EntryPoint[F]] =
def apply[F[_] : Async : Env : LoggerFactory : Random](serviceName: String,
env: DwollaEnvironment,
logTraces: Boolean,
dispatcher: Dispatcher[F]): Resource[F, EntryPoint[F]] =
logTraces
.guard[Option]
.traverse { _ =>
LoggerFactory[F]
.create
.toResource
.flatMap { implicit logger =>
Dispatcher.sequential(true)
.map(new LoggingSpanExporter(_))
.map(SimpleSpanProcessor.create)
.map { implicit logger =>
SimpleSpanProcessor.create(new LoggingSpanExporter(dispatcher))
}
}
.flatMap(buildOtel(serviceName, env, _))
.flatMap(buildOtel(serviceName, env, _, AwsXrayIdGenerator(dispatcher)))

def apply[F[_] : Async : Env : LoggerFactory : Random](serviceName: String,
env: DwollaEnvironment,
logTraces: Boolean): Resource[F, EntryPoint[F]] =
Dispatcher.sequential(true).flatMap(OpenTelemetryAtDwolla(serviceName, env, logTraces, _))

private def buildOtel[F[_] : Sync : Env](serviceName: String,
env: DwollaEnvironment,
loggingProcessor: Option[SpanProcessor],
awsXrayIdGenerator: AwsXrayIdGenerator[F],
): Resource[F, EntryPoint[F]] =
OpenTelemetry.entryPoint(globallyRegister = true) { sdkBuilder =>
// TODO consider whether to use the OpenTelemetry SDK Autoconfigure module to support all the environment variables https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure
Expand Down Expand Up @@ -86,7 +86,7 @@ object OpenTelemetryAtDwolla {
.merge(Ec2Resource.get())
.merge(EcsResource.get())
}
.setIdGenerator(AwsXrayIdGenerator.getInstance())
.setIdGenerator(awsXrayIdGenerator)
}(_ addSpanProcessor _)
.build()
}
Expand Down

0 comments on commit 0c736cd

Please sign in to comment.