Replies: 5 comments 2 replies
-
|
Hey, I will take a look next week. |
Beta Was this translation helpful? Give feedback.
-
|
Dependening on the platform, you can do things slightly differently. Here is an example: val runtime0 = {
IORuntimeBuilder()
.transformCompute { ec => wrapExecutionContext(ec, localSpan) }
.transformBlocking { ec => wrapExecutionContext(ec, localSpan) }
.build()
}
override protected def runtime: IORuntime = runtime
def wrapExecutionContext(ec: ExecutionContext): ExecutionContext = {
new ExecutionContext {
def execute(runnable: Runnable): Unit = {
// get the current span
val ctx = io.opentelemetry.api.trace.Span.current().getSpanContext
ec.execute(new Runnable {
def run(): Unit = {
if (ctx.isValid)
profiler.setTracingContext(span.spanId, 0)
try {
runnable.run()
} finally {
if (ctx.isValid) profiler.setTracingContext(0, 0)
}
}
})
}
def reportFailure(cause: Throwable): Unit = ec.reportFailure(cause)
}
}
def main: IO[Unit] = {
// make `otel4s` use the `context-storage`-backed IOLocal
given LocalProvider[IO, Context] = IOLocalContextStorage.localProvider[IO]
OtelJava.autoConfigured[IO]().use { otelJava =>
... // do the rest
}
}However, if you want to use OpenTelemetry Java Agent, it won't work out of the box. In this case, you can use otel4s distribution of the OTeL Java Agent, here are the details: https://typelevel.org/otel4s/oteljava/agent.html. |
Beta Was this translation helpful? Give feedback.
-
|
If you want to use
In this case, we should unseal |
Beta Was this translation helpful? Give feedback.
-
|
Okay, so I'm using otel4s-sdk and I've managed to make it work here: simple-scala-tooling/sls#55 But we've found the issue with IOLocals and I'm not sure if this is intended or is it a bug: //> using scala 3.7.3
//> using dep org.typelevel::cats-effect:3.6.3
import scala.concurrent.ExecutionContext
import java.util.UUID
import cats.effect.IOFiber
import cats.effect.IOApp
import cats.effect.IO
import cats.effect.unsafe.IORuntime
import cats.syntax.all.*
import cats.effect.IOLocal
object EEE extends IOApp.Simple {
var variabl: Option[Int] = None
var loc: IOLocal[Int] = null
def wrap(ec: ExecutionContext): ExecutionContext = new ExecutionContext {
def execute(runnable: Runnable): Unit = {
val res = try { loc.unsafeThreadLocal().get() } catch { case _: Throwable => 2 }
ec.execute(() => {
variabl = res.some
runnable.run()
})
}
def reportFailure(cause: Throwable): Unit = ec.reportFailure(cause)
}
override protected def runtime: IORuntime = IORuntime.builder().transformCompute(wrap).transformBlocking(wrap).build()
def run: IO[Unit] = IOLocal(0).flatMap { loc0 =>
this.loc = loc0
loc.set(1) *> IO(println(variabl)) *> // prints 2 which is default
IO.cede *> IO(println(variabl)) *> // prints 1 because IO.cede created new fiber
loc.set(-1) *> IO(println(variabl)) *> // still prints 1 because IOLocal.set does not create new fiber
IO.cede *> IO(println(variabl)) *> // prints -1 because IO.cede reschedules the fiber
}
}if you run this with What I was expecting here to happen was to have: This basically makes it impossible to track the tracing context which was the initial point of this discussion via custom executor. The current workaround is to create a wrapper on Tracer that calls IO.cede after and before the actual thunk of the trace. The reason why this breaks tracing is if we run: ec.execute(new Runnable {
def run(): Unit = {
if (ctx.isValid)
profiler.setTracingContext(span.spanId, 0)
|
Beta Was this translation helpful? Give feedback.
-
|
I tried to use https://github.com/grafana/otel-profiling-java in my otel4s demo: https://github.com/iRevive/otel4s-showcase/pull/1/files. It seems to be working. Even though the profile. 1. No data
2. CE calls
3. fs2 calls
4. gRPC calls
|
Beta Was this translation helpful? Give feedback.




Uh oh!
There was an error while loading. Please reload this page.
-
Hey, I've been working to port https://github.com/grafana/otel-profiling-java/tree/6ddc19fe2e37ad1b60ec26baf613a049c2be30e5 to otel4s and I managed to hack a working prototype.
This is proof of concept that I've created:
And the span ID can then be used to find flamegraph of given trace span:

The issue is that I'm quite unsure the implementation details of how we can set profiler context to span ID.
Right now I've created IOLocal with custom IORuntime, but maybe there is a better way to achieve it ?
Beta Was this translation helpful? Give feedback.
All reactions