Skip to content

Commit

Permalink
rework tracing and instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
patsta32 committed Aug 9, 2024
1 parent 6811d95 commit 462b383
Show file tree
Hide file tree
Showing 30 changed files with 647 additions and 491 deletions.
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import sbt.Keys.cleanFiles
ThisBuild / scalaVersion := Dependencies.scalaVersion
scalaVersion := Dependencies.scalaVersion

val releaseVersion = sys.env.getOrElse("TAG", "2.0.108")
val releaseVersion = sys.env.getOrElse("TAG", "2.0.0-alpha.rc.4")
addCommandAlias("packageSmithy4Play", "smithy4play/package")
addCommandAlias("publishSmithy4Play", "smithy4play/publish")
addCommandAlias("publishSmithy4Play", "smithy4play/publish;smithy4playInstrumentation/publish")
addCommandAlias("publishLocalWithInstrumentation", "publishLocalSmithy4PlayInstrumentation;publishLocalSmithy4Play")
addCommandAlias("publishLocalSmithy4PlayInstrumentation", "smithy4playInstrumentation/publishLocal")
addCommandAlias("publishLocalSmithy4Play", "smithy4play/publishLocal")
Expand Down
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ addSbtPlugin("com.codecommit" %% "sbt-github-packages" % "0.5.3")

addSbtPlugin("org.scalameta" %% "sbt-scalafmt" % "2.5.2")

addSbtPlugin("org.playframework" %% "sbt-plugin" % "3.0.4")
addSbtPlugin("org.playframework" %% "sbt-plugin" % "3.0.5")
addSbtPlugin("org.scoverage" %% "sbt-scoverage" % "2.0.12")
addSbtPlugin("com.disneystreaming.smithy4s" %% "smithy4s-sbt-codegen" % "0.18.22")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,5 @@ object Smithy4PlaySingleton {
private val SPAN_NAME = "play.request"

private val spanKindExtractor = SpanKindExtractor.alwaysServer()
private val INSTRUMENTER = Instrumenter
.builder[Void, Void](GlobalOpenTelemetry.get, "io.opentelemetry.smtihyt4play", (s) => SPAN_NAME)
.setEnabled(true)
.buildInstrumenter(spanKindExtractor)

.pipe { (v: Instrumenter[Void, Void]) =>
println(v.toString)
println("shouldstart: " + v.shouldStart(Context.root(), null))
v
}

def test() = {
println("Smithy4PlaySingleton test")
}

def shouldStart(context: Context): Boolean = {
try {
INSTRUMENTER.shouldStart(context, null)
} catch
case e: Exception => {
e.printStackTrace()
println(e.getMessage)
println(e.getCause)
false
}

}

def instrumenter() = INSTRUMENTER

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static de.innfactory.smithy4play.instrumentation.Smithy4PlaySingleton.test;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.SpanBuilder;
Expand Down Expand Up @@ -54,17 +53,15 @@ public static void onEnter(
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {

System.out.println("TestInstrumentation ApplyAdvice onEnter " + test);
//System.out.println("TestInstrumentation ApplyAdvice onEnter " + test);
// span.addEvent("ADVICE smithy4play " + test);
test();
Context parentContext = currentContext();
Boolean shouldStart = Smithy4PlaySingleton.shouldStart(parentContext);
System.out.println("TestInstrumentation ApplyAdvice shouldStart " + shouldStart);
//System.out.println("TestInstrumentation ApplyAdvice shouldStart " + shouldStart);
Span mySpan = GlobalOpenTelemetry.get().getTracer("smithy4play").spanBuilder("test span").startSpan();
System.out.println("TestInstrumentation ApplyAdvice mySpan " + mySpan.getSpanContext().getSpanId());
//System.out.println("TestInstrumentation ApplyAdvice mySpan " + mySpan.getSpanContext().getSpanId());
context = mySpan.storeInContext(parentContext);
Scope myScope = mySpan.makeCurrent();
System.out.println("TestInstrumentation ApplyAdvice should start");
//System.out.println("TestInstrumentation ApplyAdvice should start");
scope = myScope;
}

Expand All @@ -91,7 +88,7 @@ public static void stopTraceOnResponse(
throwable.printStackTrace();
}
if (context != null) {
System.out.println("TestInstrumentation ApplyAdvice onExit update update Span name");
// System.out.println("TestInstrumentation ApplyAdvice onExit update update Span name");
// Span.fromContext(context).updateName(testout);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.innfactory.smithy4play.client

import cats.data.{ EitherT, Kleisli }
import cats.data.EitherT
import play.api.libs.ws.{ writeableOf_ByteArray, WSClient, WSResponse }
import smithy4s.client.UnaryLowLevelClient
import smithy4s.http.{ CaseInsensitive, HttpRequest, HttpResponse }
Expand All @@ -16,22 +16,22 @@ class Smithy4PlayWsClient[Alg[_[_, _, _, _, _]]](
requestIsSuccessful: (Hints, HttpResponse[Blob]) => Boolean = matchStatusCodeForResponse,
explicitDefaultsEncoding: Boolean = true
)(implicit ec: ExecutionContext, wsClient: WSClient)
extends UnaryLowLevelClient[RunnableClientRequest, HttpRequest[Blob], HttpResponse[Blob]] {
extends UnaryLowLevelClient[FinishedClientResponse, HttpRequest[Blob], HttpResponse[Blob]] {

val underlyingClient = new SmithyPlayClient[Alg, Smithy4PlayWsClient[Alg]](
baseUri = baseUri,
service = service,
client = this,
middleware = middleware,
requestIsSuccessful = (_, _) => true,
requestIsSuccessful = requestIsSuccessful,
toSmithy4sClient = x => x
)

def transformer(): Alg[Kind1[ClientFinishedResponse]#toKind5] =
def transformer(): Alg[Kind1[RunnableClientResponse]#toKind5] =
underlyingClient.service.algebra(underlyingClient.compiler)

private def buildPath(req: HttpRequest[Blob]): String =
baseUri + req.uri.path.mkString("/")
baseUri + req.uri.path.mkString("/", "/", "")

private def toHeaders(request: HttpRequest[Blob]): List[(String, String)] =
request.headers.flatMap { case (insensitive, strings) =>
Expand All @@ -52,7 +52,7 @@ class Smithy4PlayWsClient[Alg[_[_, _, _, _, _]]](

override def run[Output](
request: HttpRequest[Blob]
)(responseCB: HttpResponse[Blob] => RunnableClientRequest[Output]): RunnableClientRequest[Output] = Kleisli { _ =>
)(responseCB: HttpResponse[Blob] => FinishedClientResponse[Output]): FinishedClientResponse[Output] = {
val clientResponse = wsClient
.url(buildPath(request))
.withQueryStringParameters(toQueryParameters(request): _*)
Expand All @@ -63,13 +63,7 @@ class Smithy4PlayWsClient[Alg[_[_, _, _, _, _]]](

val httpResponse = clientResponse.map(wsRequestToResponse)

println("run ws client")

EitherT(httpResponse.flatMap { httpResponse =>
println("httpresponse present and running internally")
val v = responseCB(httpResponse).run(() => httpResponse).value
v
})
EitherT(httpResponse.flatMap(responseCB(_).value))

}
}
Expand All @@ -81,6 +75,6 @@ object Smithy4PlayWsClient {
middleware: Endpoint.Middleware[Smithy4PlayWsClient[Alg]],
requestIsSuccessful: (Hints, HttpResponse[Blob]) => Boolean = matchStatusCodeForResponse,
explicitDefaultsEncoding: Boolean = true
)(implicit ec: ExecutionContext, wsClient: WSClient): Alg[Kind1[ClientFinishedResponse]#toKind5] =
)(implicit ec: ExecutionContext, wsClient: WSClient): Alg[Kind1[RunnableClientResponse]#toKind5] =
new Smithy4PlayWsClient(baseUri, service, middleware, requestIsSuccessful, explicitDefaultsEncoding).transformer()
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package de.innfactory.smithy4play.client

import cats.implicits.catsSyntaxApplicativeId
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
import de.innfactory.smithy4play.client.RunnableClientRequest
import de.innfactory.smithy4play.client.core.Smithy4PlayClientCompiler
import de.innfactory.smithy4play.codecs.{ Codec, EndpointContentTypes }
import de.innfactory.smithy4play.routing.internal.toSmithy4sHttpUri
import smithy4s.capability.MonadThrowLike
import smithy4s.{ Blob, Endpoint, Hints, Service }
import smithy4s.http.{
CaseInsensitive,
HttpDiscriminator,
HttpEndpoint,
HttpMethod,
HttpRequest,
HttpResponse,
Expand All @@ -20,7 +14,7 @@ import smithy4s.http.{
HttpUriScheme,
Metadata
}
import smithy4s.client.{ UnaryClientCodecs, UnaryClientCompiler, UnaryClientEndpoint, UnaryLowLevelClient }
import smithy4s.client.UnaryLowLevelClient
import smithy4s.interopcats.monadThrowShim

import scala.concurrent.{ ExecutionContext, Future }
Expand All @@ -30,7 +24,7 @@ class SmithyPlayClient[Alg[_[_, _, _, _, _]], Client](
val service: smithy4s.Service[Alg],
client: Client,
middleware: Endpoint.Middleware[Client],
toSmithy4sClient: Client => UnaryLowLevelClient[RunnableClientRequest, HttpRequest[Blob], HttpResponse[Blob]],
toSmithy4sClient: Client => UnaryLowLevelClient[FinishedClientResponse, HttpRequest[Blob], HttpResponse[Blob]],
requestIsSuccessful: (Hints, HttpResponse[Blob]) => Boolean,
explicitDefaultsEncoding: Boolean = true
)(implicit executionContext: ExecutionContext)
Expand All @@ -48,21 +42,21 @@ class SmithyPlayClient[Alg[_[_, _, _, _, _]], Client](
smithy4s.http.amazonErrorTypeHeader
)

val clientCodecBuilder: HttpUnaryClientCodecs.Builder[RunnableClientRequest, HttpRequest[Blob], HttpResponse[Blob]] =
val clientCodecBuilder: HttpUnaryClientCodecs.Builder[ClientResponse, HttpRequest[Blob], HttpResponse[Blob]] =
HttpUnaryClientCodecs
.builder[RunnableClientRequest]
.withErrorDiscriminator(HttpDiscriminator.fromResponse(errorHeaders, _).pure[RunnableClientRequest])
.builder[ClientResponse]
.withErrorDiscriminator(HttpDiscriminator.fromResponse(errorHeaders, _).pure[ClientResponse])
.withMetadataDecoders(Metadata.Decoder)
.withMetadataEncoders(
Metadata.Encoder.withExplicitDefaultsEncoding(explicitDefaultsEncoding)
)
.withBaseRequest(_ => baseRequest.pure[RunnableClientRequest])
.withBaseRequest(_ => baseRequest.pure[ClientResponse])

val compiledClientCodec
: EndpointContentTypes => HttpUnaryClientCodecs.Builder[RunnableClientRequest, HttpRequest[Blob], HttpResponse[Blob]] =
: EndpointContentTypes => HttpUnaryClientCodecs.Builder[ClientResponse, HttpRequest[Blob], HttpResponse[Blob]] =
buildClientCodecFromBase(clientCodecBuilder)

val compiler: service.FunctorEndpointCompiler[ClientFinishedResponse] = Smithy4PlayClientCompiler[Alg, Client](
val compiler: service.FunctorEndpointCompiler[RunnableClientResponse] = Smithy4PlayClientCompiler[Alg, Client](
service = service,
client = client,
toSmithy4sClient = toSmithy4sClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,50 @@ import scala.concurrent.{ Await, ExecutionContext }

object SmithyPlayTestUtils {

implicit class EnhancedResponse[O](response: RunnableClientRequest[O]) {
implicit class EnhancedResponse[O](response: RunnableClientResponse[O]) {
def awaitRight(implicit
ec: ExecutionContext,
timeout: Duration = 5.seconds
): HttpResponse[O] = {
val result = Await.result(
response.tapWith((ctx, o) => ctx.apply().copy(body = o)).run(null)
.bimap(
throwable =>
logger.error(
s"Expected Right, got Left: ${throwable.toString} Error: ${throwable.underlying.getMessage}"
),
res => res
).value,
timeout
).toOption.get

val result = Await
.result(
response.run(identity)
.bimap(
throwable =>
logger.error(
s"Expected Right, got Left: ${throwable.toString} ${throwable.getMessage} ${throwable.httpResponse.statusCode} Error: ${throwable.underlying.getMessage} ${throwable.underlying.getCause}"
),
identity
)
.value,
timeout
)
.toOption
.get

result
}


def awaitLeft(implicit
ec: ExecutionContext,
timeout: Duration = 5.seconds
): HttpResponse[Throwable] = {
val result = Await.result(
response.run(null)
.bimap(
throwable => throwable
,
res => logger.error(
s"Expected Left, got Right: ${res.toString}"
val result = Await
.result(
response.run(identity)
.bimap(
identity,
res => logger.error(s"Expected Left, got Right: ${res.toString}")
)
).value,
timeout
).swap.toOption.get
.value,
timeout
)
.swap
.toOption
.get

result.httpResponse.copy(body = result.underlying)
}
}



}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package de.innfactory.smithy4play.client.core

import de.innfactory.smithy4play.client.{ClientFinishedResponse, OWrapper, RunnableClientRequest}
import de.innfactory.smithy4play.client.{ClientResponse, FinishedClientResponse, RunnableClientResponse}
import de.innfactory.smithy4play.codecs.EndpointContentTypes
import smithy4s.{Blob, Endpoint, Hints}
import smithy4s.capability.MonadThrowLike
import smithy4s.client.{UnaryClientCodecs, UnaryClientEndpoint, UnaryLowLevelClient}
import smithy4s.client.UnaryLowLevelClient
import smithy4s.http.{HttpRequest, HttpResponse, HttpUnaryClientCodecs}
import smithy4s.kinds.{Kind1, PolyFunction5}
import smithy4s.server.UnaryServerCodecs

import scala.concurrent.ExecutionContext

Expand All @@ -27,16 +25,16 @@ object Smithy4PlayClientCompiler {
def apply[Alg[_[_, _, _, _, _]], Client](
service: smithy4s.Service[Alg],
client: Client,
toSmithy4sClient: Client => UnaryLowLevelClient[RunnableClientRequest, HttpRequest[Blob], HttpResponse[Blob]],
codecs: EndpointContentTypes => HttpUnaryClientCodecs.Builder[RunnableClientRequest, HttpRequest[Blob], HttpResponse[Blob]],
toSmithy4sClient: Client => UnaryLowLevelClient[FinishedClientResponse, HttpRequest[Blob], HttpResponse[Blob]],
codecs: EndpointContentTypes => HttpUnaryClientCodecs.Builder[ClientResponse, HttpRequest[Blob], HttpResponse[Blob]],
middleware: Endpoint.Middleware[Client],
isSuccessful: (Hints, HttpResponse[Blob]) => Boolean
)(implicit F: MonadThrowLike[RunnableClientRequest], ec: ExecutionContext): service.FunctorEndpointCompiler[ClientFinishedResponse] = {
)(implicit F: MonadThrowLike[ClientResponse], ec: ExecutionContext): service.FunctorEndpointCompiler[RunnableClientResponse] = {

new service.FunctorEndpointCompiler[ClientFinishedResponse] {
new service.FunctorEndpointCompiler[RunnableClientResponse] {
def apply[I, E, O, SI, SO](
endpoint: service.Endpoint[I, E, O, SI, SO]
): I => ClientFinishedResponse[O] = {
): I => RunnableClientResponse[O] = {

val transformedClient =
middleware.prepare(service)(endpoint).apply(client)
Expand All @@ -46,15 +44,13 @@ object Smithy4PlayClientCompiler {
val contentType = resolveContentType(endpoint.hints, service.hints, Seq.empty, None)
val codec = codecs(contentType).build()

val clientEndpoint: I => RunnableClientRequest[O] = UnaryClientEndpoint(
val clientEndpoint: I => RunnableClientResponse[O] = Smithy4PlayClientEndpoint(
adaptedClient,
codec.apply(endpoint.schema),
isSuccessful.curried(endpoint.hints)
)

clientEndpoint.andThen(q => {
q.tapWith((ctx, o) => ctx.apply().copy(body = o))
})
clientEndpoint
}
}
}
Expand Down
Loading

0 comments on commit 462b383

Please sign in to comment.