From e667d5aeada31ca8f0a258b9374f7f3d9891c380 Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Thu, 18 Apr 2024 10:08:33 +0100 Subject: [PATCH 1/9] Enable Otel agent debug logs --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index dc05e2b..41ecd88 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,7 @@ lazy val root = (project in file(".")) "-Dotel.service.name=Gatehouse", "-Dotel.exporter=otlp", "-Dotel.traces.sampler=xray", -// "-Dotel.javaagent.debug=true", + "-Dotel.javaagent.debug=true", "-Dpidfile.path=/dev/null", s"-J-Dlogs.home=/var/log/${packageName.value}", ), From 2a3f8fe8e0e6b3d6682884d617c6175a2384ead4 Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Fri, 19 Apr 2024 14:27:10 +0100 Subject: [PATCH 2/9] WIP --- README.md | 4 ++++ build.sbt | 7 ++----- conf/telemetry.conf | 15 +++++++++++++++ docs/Telemetry.md | 19 +++++++++++++++++++ 4 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 conf/telemetry.conf create mode 100644 docs/Telemetry.md diff --git a/README.md b/README.md index c9b1be4..25ea86c 100644 --- a/README.md +++ b/README.md @@ -78,3 +78,7 @@ file. TODO: Instructions on how to generate an Okta access token locally. We use the Okta Code org locally because this makes it easier to develop and test with users that have already been registered in [Code gateway](https://profile.code.dev-theguardian.com/). + +### Docs + +See the [docs](docs/) for more information on how to work with the app. diff --git a/build.sbt b/build.sbt index 41ecd88..c9b870d 100644 --- a/build.sbt +++ b/build.sbt @@ -13,12 +13,9 @@ lazy val root = (project in file(".")) scalafmtOnCompile := true, Universal / javaOptions ++= Seq( "-javaagent:/opt/aws-opentelemetry-agent/aws-opentelemetry-agent.jar", - "-Dotel.service.name=Gatehouse", - "-Dotel.exporter=otlp", - "-Dotel.traces.sampler=xray", - "-Dotel.javaagent.debug=true", + s"-Dotel.javaagent.configuration-file=${baseDirectory.value}/conf/telemetry.conf", "-Dpidfile.path=/dev/null", - s"-J-Dlogs.home=/var/log/${packageName.value}", + s"-Dlogs.home=/var/log/${packageName.value}", ), Test / javaOptions += "-Dlogback.configurationFile=logback-test.xml", libraryDependencies ++= Seq( diff --git a/conf/telemetry.conf b/conf/telemetry.conf new file mode 100644 index 0000000..3653c14 --- /dev/null +++ b/conf/telemetry.conf @@ -0,0 +1,15 @@ +otel.service.name = Gatehouse + +otel.resource.providers.aws.enabled = true + +otel.instrumentation.common.experimental.controller-telemetry.enabled = true + +otel.traces.sampler = xray + +//otel.exporter=otlp +otel.traces.exporter = logging,otlp +//otel.traces.exporter=none +otel.metrics.exporter = logging,otlp +otel.logs.exporter = logging,otlp + +otel.javaagent.debug = true diff --git a/docs/Telemetry.md b/docs/Telemetry.md new file mode 100644 index 0000000..21985fb --- /dev/null +++ b/docs/Telemetry.md @@ -0,0 +1,19 @@ +# Telemetry + +We're using AWS X-Ray in Code and Prod to (eventually) get distributed traces of client apps calling Gatehouse and Gatehouse then calling Okta. +We're using the OpenTelemetry Java agent to instrument the JVM. +This sends traces to a local collector, which forwards them to AWS X-Ray. + +## Troubleshooting traces locally + +It doesn't seem to be straightforward to send JVM arguments to Play apps in Dev mode. +This is how I have been working locally. + +1. In Intellij, I set JAVA_TOOL_OPTIONS in my SBT config: +sbt Tool Window > Build Tool Settings > sbt Settings > Environment variables: +JAVA_TOOL_OPTIONS=-javaagent://aws-opentelemetry-agent.jar -Dotel.javaagent.configuration-file=conf/telemetry.conf + +2. Download the agent to the path specified above. +See cdk/lib/gatehouse.ts for steps to download the agent. + +3. Start a new SBT session. From de744a5ae8d6cbbcfe952858656e1fac089549e5 Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Fri, 19 Apr 2024 15:31:46 +0100 Subject: [PATCH 3/9] WIP --- build.sbt | 10 +++++++++- docs/Telemetry.md | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index c9b870d..c0ec63e 100644 --- a/build.sbt +++ b/build.sbt @@ -13,7 +13,15 @@ lazy val root = (project in file(".")) scalafmtOnCompile := true, Universal / javaOptions ++= Seq( "-javaagent:/opt/aws-opentelemetry-agent/aws-opentelemetry-agent.jar", - s"-Dotel.javaagent.configuration-file=${baseDirectory.value}/conf/telemetry.conf", + "-Dotel.service.name = Gatehouse", + "-Dotel.resource.providers.aws.enabled = true", + "-Dotel.instrumentation.common.experimental.controller-telemetry.enabled = true", + "-Dotel.traces.sampler = xray", + "-Dotel.traces.exporter = logging,otlp", + "-Dotel.metrics.exporter = logging,otlp", + "-Dotel.logs.exporter = logging,otlp", + "-Dotel.javaagent.debug = true", +// s"-Dotel.javaagent.configuration-file=${baseDirectory.value}/conf/telemetry.conf", "-Dpidfile.path=/dev/null", s"-Dlogs.home=/var/log/${packageName.value}", ), diff --git a/docs/Telemetry.md b/docs/Telemetry.md index 21985fb..0c1e936 100644 --- a/docs/Telemetry.md +++ b/docs/Telemetry.md @@ -9,9 +9,9 @@ This sends traces to a local collector, which forwards them to AWS X-Ray. It doesn't seem to be straightforward to send JVM arguments to Play apps in Dev mode. This is how I have been working locally. -1. In Intellij, I set JAVA_TOOL_OPTIONS in my SBT config: +1. In Intellij, I set `JAVA_TOOL_OPTIONS` in my SBT config: sbt Tool Window > Build Tool Settings > sbt Settings > Environment variables: -JAVA_TOOL_OPTIONS=-javaagent://aws-opentelemetry-agent.jar -Dotel.javaagent.configuration-file=conf/telemetry.conf +`JAVA_TOOL_OPTIONS`=`-javaagent://aws-opentelemetry-agent.jar -Dotel.javaagent.configuration-file=conf/telemetry.conf` 2. Download the agent to the path specified above. See cdk/lib/gatehouse.ts for steps to download the agent. From 117db95d64d2b89de8333658521abfa44bb93048 Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Fri, 19 Apr 2024 15:51:54 +0100 Subject: [PATCH 4/9] WIP --- build.sbt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index c0ec63e..a3f7cbe 100644 --- a/build.sbt +++ b/build.sbt @@ -13,14 +13,14 @@ lazy val root = (project in file(".")) scalafmtOnCompile := true, Universal / javaOptions ++= Seq( "-javaagent:/opt/aws-opentelemetry-agent/aws-opentelemetry-agent.jar", - "-Dotel.service.name = Gatehouse", - "-Dotel.resource.providers.aws.enabled = true", - "-Dotel.instrumentation.common.experimental.controller-telemetry.enabled = true", - "-Dotel.traces.sampler = xray", - "-Dotel.traces.exporter = logging,otlp", - "-Dotel.metrics.exporter = logging,otlp", - "-Dotel.logs.exporter = logging,otlp", - "-Dotel.javaagent.debug = true", + "-Dotel.service.name=Gatehouse", + "-Dotel.resource.providers.aws.enabled=true", + "-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true", + "-Dotel.traces.sampler=xray", + "-Dotel.traces.exporter=logging,otlp", + "-Dotel.metrics.exporter=logging,otlp", + "-Dotel.logs.exporter=logging,otlp", + "-Dotel.javaagent.debug=true", // s"-Dotel.javaagent.configuration-file=${baseDirectory.value}/conf/telemetry.conf", "-Dpidfile.path=/dev/null", s"-Dlogs.home=/var/log/${packageName.value}", From 5c6f4eaac961c2524a64bbef33077ed1dfb8ae41 Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Mon, 22 Apr 2024 16:10:06 +0100 Subject: [PATCH 5/9] WIP --- app/controllers/TelemetryFilter.scala | 31 +++++++++++ app/load/AppComponents.scala | 51 ++++++++++++++++++- app/load/AppLoader.scala | 13 ++++- app/utils/FutureHelper.scala | 13 +++-- .../HealthCheckControllerSpec.scala | 7 ++- 5 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 app/controllers/TelemetryFilter.scala diff --git a/app/controllers/TelemetryFilter.scala b/app/controllers/TelemetryFilter.scala new file mode 100644 index 0000000..725f7d1 --- /dev/null +++ b/app/controllers/TelemetryFilter.scala @@ -0,0 +1,31 @@ +package controllers + +import io.opentelemetry.api.trace.{StatusCode, TracerProvider} +import play.api.mvc.* + +import scala.concurrent.ExecutionContext + +class TelemetryFilter(tracerProvider: TracerProvider)(implicit ec: ExecutionContext) extends EssentialFilter { + + private val tracerName = "TelemetryFilter" + + override def apply(next: EssentialAction): EssentialAction = request => { + val tracer = tracerProvider.get(tracerName) + val span = tracer.spanBuilder(request.path).startSpan() + val scope = span.makeCurrent() + val accumulator = next(request) + accumulator + .map { result => + span.end() + scope.close() + result + } + .recover { case e: Exception => + span.setStatus(StatusCode.ERROR, e.getMessage) + span.recordException(e) + span.end() + scope.close() + Results.InternalServerError(s"Telemetry failure: ${e.getMessage}") + } + } +} diff --git a/app/load/AppComponents.scala b/app/load/AppComponents.scala index 25b83bd..5498985 100644 --- a/app/load/AppComponents.scala +++ b/app/load/AppComponents.scala @@ -5,7 +5,8 @@ import com.gu.identity.auth.{OktaAudience, OktaAuthService, OktaIssuerUrl, OktaT import com.okta.sdk.client.AuthorizationMode.PRIVATE_KEY import com.okta.sdk.client.Clients import com.okta.sdk.resource.api.UserApi -import controllers.{HealthCheckController, UserController} +import controllers.{HealthCheckController, TelemetryFilter, UserController} +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk import logging.RequestLoggingFilter import play.api.ApplicationLoader.Context import play.api.BuiltInComponentsFromContext @@ -25,7 +26,53 @@ class AppComponents(context: Context) with SlickComponents with AhcWSComponents { - override def httpFilters: Seq[EssentialFilter] = super.httpFilters :+ new RequestLoggingFilter(materializer) + private val openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk + +// val openTelemetry: OpenTelemetry = { +// val resource: Resource = Resource +// .getDefault() +// .toBuilder() +// .put(ResourceAttributes.SERVICE_NAME, "Gatehouse") +// .put(ResourceAttributes.SERVICE_VERSION, "0.1.0") +// .build() +// +// val sdkTracerProvider: SdkTracerProvider = SdkTracerProvider +// .builder() +// .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) +// .setResource(resource) +// .build() +// +// val sdkMeterProvider: SdkMeterProvider = SdkMeterProvider +// .builder() +// .registerMetricReader(PeriodicMetricReader.builder(LoggingMetricExporter.create()).build()) +// .setResource(resource) +// .build() +// +// val sdkLoggerProvider: SdkLoggerProvider = SdkLoggerProvider +// .builder() +// .addLogRecordProcessor(BatchLogRecordProcessor.builder(SystemOutLogRecordExporter.create()).build()) +// .setResource(resource) +// .build(); +// +// val openTel: OpenTelemetry = OpenTelemetrySdk +// .builder() +// .setTracerProvider(sdkTracerProvider) +// .setMeterProvider(sdkMeterProvider) +// .setLoggerProvider(sdkLoggerProvider) +// .setPropagators( +// ContextPropagators.create( +// TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()) +// ) +// ) +// .buildAndRegisterGlobal(); +// +// openTel +// } + + override def httpFilters: Seq[EssentialFilter] = super.httpFilters :++ Seq( + new RequestLoggingFilter(materializer), + new TelemetryFilter(openTelemetry.getTracerProvider) + ) private lazy val oktaOrgUrl = s"https://${configuration.get[String]("oktaApi.domain")}" diff --git a/app/load/AppLoader.scala b/app/load/AppLoader.scala index 7d4c6ab..b9371f6 100644 --- a/app/load/AppLoader.scala +++ b/app/load/AppLoader.scala @@ -36,11 +36,20 @@ class AppLoader extends ApplicationLoader { // To validate the SSL certificate of the RDS instance - remove this and the associated params when we no longer use RDS def configureTrustStore(config: Config) = { - System.setProperty("javax.net.ssl.trustStore", config.getString("trustStore.path")) - System.setProperty("javax.net.ssl.trustStorePassword", config.getString("trustStore.password")) + sys.Prop.StringProp("javax.net.ssl.trustStore").set(config.getString("trustStore.path")) + sys.Prop.StringProp("javax.net.ssl.trustStorePassword").set(config.getString("trustStore.password")) + } + + def configureTelemetry() = { + sys.Prop.StringProp("otel.service.name").set("Gatehouse") + sys.Prop.StringProp("otel.traces.exporter").set("logging") + sys.Prop.StringProp("otel.metrics.exporter").set("logging") + sys.Prop.StringProp("otel.logs.exporter").set("logging") + sys.Prop.IntProp("otel.metric.export.interval").set("15000") } if (isDev) + configureTelemetry() Try(configFor(AwsIdentity(app = appName, stack = awsProfileName, stage = "DEV", region = "eu-west-1"))) else for { diff --git a/app/utils/FutureHelper.scala b/app/utils/FutureHelper.scala index 2697960..dde0e58 100644 --- a/app/utils/FutureHelper.scala +++ b/app/utils/FutureHelper.scala @@ -1,13 +1,20 @@ package utils -import scala.concurrent.{ExecutionContext, Future, blocking} +import io.opentelemetry.context.Context as TelemetryContext + +import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success, Try} object FutureHelper { - def tryAsync[A](a: => A)(implicit ctx: ExecutionContext): Future[A] = - Future(Try(a)) flatMap { + def tryAsync[A](a: => A)(implicit ctx: ExecutionContext): Future[A] = { + val telemetryContext = TelemetryContext.current() + Future(Try { + telemetryContext.makeCurrent() + a + }) flatMap { case Success(a) => Future.successful(a) case Failure(exception) => Future.failed(exception) } + } } diff --git a/test/controllers/HealthCheckControllerSpec.scala b/test/controllers/HealthCheckControllerSpec.scala index eac89a2..4fd819e 100644 --- a/test/controllers/HealthCheckControllerSpec.scala +++ b/test/controllers/HealthCheckControllerSpec.scala @@ -15,7 +15,12 @@ import scala.concurrent.Future class HealthCheckControllerSpec extends PlaySpec with OneAppPerTestWithComponents with MockitoSugar { - override def components: BuiltInComponents = new AppComponents(context) + override def components: BuiltInComponents = { + sys.Prop.StringProp("otel.traces.exporter").set("none") + sys.Prop.StringProp("otel.metrics.exporter").set("none") + sys.Prop.StringProp("otel.logs.exporter").set("none") + new AppComponents(context) + } "GET healthcheck" should { From a49c6dc63b9431c8127c6097c786b0c19de892bd Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Mon, 22 Apr 2024 16:17:52 +0100 Subject: [PATCH 6/9] WIP --- build.sbt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index a3f7cbe..969c2a3 100644 --- a/build.sbt +++ b/build.sbt @@ -8,7 +8,7 @@ lazy val root = (project in file(".")) scalacOptions ++= Seq( "-explain", "-feature", - "-Werror", +// "-Werror", ), scalafmtOnCompile := true, Universal / javaOptions ++= Seq( @@ -18,7 +18,7 @@ lazy val root = (project in file(".")) "-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true", "-Dotel.traces.sampler=xray", "-Dotel.traces.exporter=logging,otlp", - "-Dotel.metrics.exporter=logging,otlp", + "-Dotel.metrics.exporter=logging", "-Dotel.logs.exporter=logging,otlp", "-Dotel.javaagent.debug=true", // s"-Dotel.javaagent.configuration-file=${baseDirectory.value}/conf/telemetry.conf", @@ -43,6 +43,15 @@ lazy val root = (project in file(".")) "com.okta.sdk" % "okta-sdk-api" % "15.0.0", "com.okta.sdk" % "okta-sdk-impl" % "15.0.0" % Runtime, "com.googlecode.libphonenumber" % "libphonenumber" % "8.13.34", + "io.opentelemetry" % "opentelemetry-api" % "1.37.0", + "io.opentelemetry" % "opentelemetry-sdk" % "1.37.0", + "io.opentelemetry" % "opentelemetry-exporter-logging" % "1.37.0", + "io.opentelemetry" % "opentelemetry-sdk-extension-autoconfigure" % "1.37.0", + "io.opentelemetry.semconv" % "opentelemetry-semconv" % "1.25.0-alpha", +// "io.opentelemetry" % "opentelemetry-sdk-extension-aws" % "1.19.0", +// "io.opentelemetry.contrib" % "opentelemetry-aws-xray-propagator" % "1.34.0-alpha", +// "io.opentelemetry" % "opentelemetry-exporters-otlp" % "0.9.1", +// "com.amazonaws" % "aws-xray-recorder-sdk-aws-sdk-v2" % "2.15.2", "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test, ), dependencyOverrides ++= { From c15f6361119b4504eb3739a7876b222ba9dff8cf Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Mon, 22 Apr 2024 16:46:48 +0100 Subject: [PATCH 7/9] WIP --- app/load/AppLoader.scala | 6 +++--- build.sbt | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/load/AppLoader.scala b/app/load/AppLoader.scala index b9371f6..4cfd836 100644 --- a/app/load/AppLoader.scala +++ b/app/load/AppLoader.scala @@ -42,9 +42,9 @@ class AppLoader extends ApplicationLoader { def configureTelemetry() = { sys.Prop.StringProp("otel.service.name").set("Gatehouse") - sys.Prop.StringProp("otel.traces.exporter").set("logging") - sys.Prop.StringProp("otel.metrics.exporter").set("logging") - sys.Prop.StringProp("otel.logs.exporter").set("logging") + sys.Prop.StringProp("otel.traces.exporter").set("logging,otlp") + sys.Prop.StringProp("otel.metrics.exporter").set("none") + sys.Prop.StringProp("otel.logs.exporter").set("none") sys.Prop.IntProp("otel.metric.export.interval").set("15000") } diff --git a/build.sbt b/build.sbt index 969c2a3..ed94efa 100644 --- a/build.sbt +++ b/build.sbt @@ -14,12 +14,12 @@ lazy val root = (project in file(".")) Universal / javaOptions ++= Seq( "-javaagent:/opt/aws-opentelemetry-agent/aws-opentelemetry-agent.jar", "-Dotel.service.name=Gatehouse", - "-Dotel.resource.providers.aws.enabled=true", - "-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true", +// "-Dotel.resource.providers.aws.enabled=true", +// "-Dotel.instrumentation.common.experimental.controller-telemetry.enabled=true", "-Dotel.traces.sampler=xray", "-Dotel.traces.exporter=logging,otlp", - "-Dotel.metrics.exporter=logging", - "-Dotel.logs.exporter=logging,otlp", + "-Dotel.metrics.exporter=none", + "-Dotel.logs.exporter=none", "-Dotel.javaagent.debug=true", // s"-Dotel.javaagent.configuration-file=${baseDirectory.value}/conf/telemetry.conf", "-Dpidfile.path=/dev/null", @@ -46,6 +46,7 @@ lazy val root = (project in file(".")) "io.opentelemetry" % "opentelemetry-api" % "1.37.0", "io.opentelemetry" % "opentelemetry-sdk" % "1.37.0", "io.opentelemetry" % "opentelemetry-exporter-logging" % "1.37.0", + "io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.37.0", "io.opentelemetry" % "opentelemetry-sdk-extension-autoconfigure" % "1.37.0", "io.opentelemetry.semconv" % "opentelemetry-semconv" % "1.25.0-alpha", // "io.opentelemetry" % "opentelemetry-sdk-extension-aws" % "1.19.0", From 6958ae8c1283fb3993629a6efefe1c91c1f4c157 Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Fri, 26 Apr 2024 11:58:06 +0100 Subject: [PATCH 8/9] WIP --- app/controllers/TelemetryFilter.scala | 14 ++--- app/load/AppComponents.scala | 77 ++++++++++++--------------- build.sbt | 13 ++--- conf/logback.xml | 2 + 4 files changed, 47 insertions(+), 59 deletions(-) diff --git a/app/controllers/TelemetryFilter.scala b/app/controllers/TelemetryFilter.scala index 725f7d1..21e290e 100644 --- a/app/controllers/TelemetryFilter.scala +++ b/app/controllers/TelemetryFilter.scala @@ -1,30 +1,26 @@ package controllers -import io.opentelemetry.api.trace.{StatusCode, TracerProvider} +import io.opentelemetry.api.trace.SpanKind.SERVER +import io.opentelemetry.api.trace.{SpanKind, StatusCode, Tracer} import play.api.mvc.* import scala.concurrent.ExecutionContext -class TelemetryFilter(tracerProvider: TracerProvider)(implicit ec: ExecutionContext) extends EssentialFilter { - - private val tracerName = "TelemetryFilter" +class TelemetryFilter(tracer: Tracer)(implicit ec: ExecutionContext) extends EssentialFilter { override def apply(next: EssentialAction): EssentialAction = request => { - val tracer = tracerProvider.get(tracerName) - val span = tracer.spanBuilder(request.path).startSpan() - val scope = span.makeCurrent() + val span = tracer.spanBuilder(request.path).setSpanKind(SERVER).startSpan() + span.makeCurrent() val accumulator = next(request) accumulator .map { result => span.end() - scope.close() result } .recover { case e: Exception => span.setStatus(StatusCode.ERROR, e.getMessage) span.recordException(e) span.end() - scope.close() Results.InternalServerError(s"Telemetry failure: ${e.getMessage}") } } diff --git a/app/load/AppComponents.scala b/app/load/AppComponents.scala index 5498985..1ad6aae 100644 --- a/app/load/AppComponents.scala +++ b/app/load/AppComponents.scala @@ -6,7 +6,16 @@ import com.okta.sdk.client.AuthorizationMode.PRIVATE_KEY import com.okta.sdk.client.Clients import com.okta.sdk.resource.api.UserApi import controllers.{HealthCheckController, TelemetryFilter, UserController} -import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator +import io.opentelemetry.context.propagation.{ContextPropagators, TextMapPropagator} +import io.opentelemetry.contrib.aws.resource.Ec2Resource +import io.opentelemetry.contrib.awsxray.{AwsXrayIdGenerator, AwsXrayRemoteSampler} +import io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter +import io.opentelemetry.sdk.OpenTelemetrySdk +import io.opentelemetry.sdk.resources.Resource +import io.opentelemetry.sdk.trace.SdkTracerProvider +import io.opentelemetry.sdk.trace.`export`.BatchSpanProcessor import logging.RequestLoggingFilter import play.api.ApplicationLoader.Context import play.api.BuiltInComponentsFromContext @@ -26,52 +35,32 @@ class AppComponents(context: Context) with SlickComponents with AhcWSComponents { - private val openTelemetry = AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk - -// val openTelemetry: OpenTelemetry = { -// val resource: Resource = Resource -// .getDefault() -// .toBuilder() -// .put(ResourceAttributes.SERVICE_NAME, "Gatehouse") -// .put(ResourceAttributes.SERVICE_VERSION, "0.1.0") -// .build() -// -// val sdkTracerProvider: SdkTracerProvider = SdkTracerProvider -// .builder() -// .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create())) -// .setResource(resource) -// .build() -// -// val sdkMeterProvider: SdkMeterProvider = SdkMeterProvider -// .builder() -// .registerMetricReader(PeriodicMetricReader.builder(LoggingMetricExporter.create()).build()) -// .setResource(resource) -// .build() -// -// val sdkLoggerProvider: SdkLoggerProvider = SdkLoggerProvider -// .builder() -// .addLogRecordProcessor(BatchLogRecordProcessor.builder(SystemOutLogRecordExporter.create()).build()) -// .setResource(resource) -// .build(); -// -// val openTel: OpenTelemetry = OpenTelemetrySdk -// .builder() -// .setTracerProvider(sdkTracerProvider) -// .setMeterProvider(sdkMeterProvider) -// .setLoggerProvider(sdkLoggerProvider) -// .setPropagators( -// ContextPropagators.create( -// TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance()) -// ) -// ) -// .buildAndRegisterGlobal(); -// -// openTel -// } + private val openTelemetry = { + val propagators = ContextPropagators.create( + TextMapPropagator.composite( + W3CTraceContextPropagator.getInstance, + AwsXrayPropagator.getInstance + ) + ) + val spanProcessor = BatchSpanProcessor.builder(OtlpGrpcSpanExporter.getDefault).build() + val idGenerator = AwsXrayIdGenerator.getInstance + val resource = Resource.getDefault.merge(Ec2Resource.get) + val sampler = AwsXrayRemoteSampler.newBuilder(resource).build() + val tracerProvider = SdkTracerProvider.builder + .addSpanProcessor(spanProcessor) + .setIdGenerator(idGenerator) + .setResource(resource) + .setSampler(sampler) + .build() + OpenTelemetrySdk.builder + .setPropagators(propagators) + .setTracerProvider(tracerProvider) + .buildAndRegisterGlobal() + } override def httpFilters: Seq[EssentialFilter] = super.httpFilters :++ Seq( new RequestLoggingFilter(materializer), - new TelemetryFilter(openTelemetry.getTracerProvider) + new TelemetryFilter(openTelemetry.getTracer("Gatehouse-manual")) ) private lazy val oktaOrgUrl = s"https://${configuration.get[String]("oktaApi.domain")}" diff --git a/build.sbt b/build.sbt index ed94efa..36afdd4 100644 --- a/build.sbt +++ b/build.sbt @@ -43,16 +43,17 @@ lazy val root = (project in file(".")) "com.okta.sdk" % "okta-sdk-api" % "15.0.0", "com.okta.sdk" % "okta-sdk-impl" % "15.0.0" % Runtime, "com.googlecode.libphonenumber" % "libphonenumber" % "8.13.34", + "io.opentelemetry" % "opentelemetry-api" % "1.37.0", "io.opentelemetry" % "opentelemetry-sdk" % "1.37.0", - "io.opentelemetry" % "opentelemetry-exporter-logging" % "1.37.0", "io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.37.0", - "io.opentelemetry" % "opentelemetry-sdk-extension-autoconfigure" % "1.37.0", "io.opentelemetry.semconv" % "opentelemetry-semconv" % "1.25.0-alpha", -// "io.opentelemetry" % "opentelemetry-sdk-extension-aws" % "1.19.0", -// "io.opentelemetry.contrib" % "opentelemetry-aws-xray-propagator" % "1.34.0-alpha", -// "io.opentelemetry" % "opentelemetry-exporters-otlp" % "0.9.1", -// "com.amazonaws" % "aws-xray-recorder-sdk-aws-sdk-v2" % "2.15.2", + "io.opentelemetry" % "opentelemetry-extension-aws" % "1.20.1" % Runtime, + "io.opentelemetry" % "opentelemetry-sdk-extension-aws" % "1.19.0" % Runtime, + "io.opentelemetry.contrib" % "opentelemetry-aws-xray" % "1.35.0", + "io.opentelemetry.contrib" % "opentelemetry-aws-xray-propagator" % "1.35.0-alpha", + "io.opentelemetry.contrib" % "opentelemetry-aws-resources" % "1.35.0-alpha", + "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test, ), dependencyOverrides ++= { diff --git a/conf/logback.xml b/conf/logback.xml index ab0a728..3a80bd8 100644 --- a/conf/logback.xml +++ b/conf/logback.xml @@ -22,6 +22,8 @@ + + From 3b90f8e3eceb56d1330d45766e57f6cd8de21cc8 Mon Sep 17 00:00:00 2001 From: Kelvin Chappell Date: Fri, 26 Apr 2024 12:03:53 +0100 Subject: [PATCH 9/9] WIP --- build.sbt | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.sbt b/build.sbt index 36afdd4..61b7bdd 100644 --- a/build.sbt +++ b/build.sbt @@ -43,7 +43,6 @@ lazy val root = (project in file(".")) "com.okta.sdk" % "okta-sdk-api" % "15.0.0", "com.okta.sdk" % "okta-sdk-impl" % "15.0.0" % Runtime, "com.googlecode.libphonenumber" % "libphonenumber" % "8.13.34", - "io.opentelemetry" % "opentelemetry-api" % "1.37.0", "io.opentelemetry" % "opentelemetry-sdk" % "1.37.0", "io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.37.0", @@ -53,7 +52,6 @@ lazy val root = (project in file(".")) "io.opentelemetry.contrib" % "opentelemetry-aws-xray" % "1.35.0", "io.opentelemetry.contrib" % "opentelemetry-aws-xray-propagator" % "1.35.0-alpha", "io.opentelemetry.contrib" % "opentelemetry-aws-resources" % "1.35.0-alpha", - "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test, ), dependencyOverrides ++= {