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 @@ + +