Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 889a7d4

Browse files
authored
Merge pull request #948 from iRevive/feature/otel-agent
2 parents 25648b2 + 4f4da79 commit 889a7d4

File tree

2 files changed

+27
-40
lines changed

2 files changed

+27
-40
lines changed

oteljava/context-storage/src/main/scala/org/typelevel/otel4s/oteljava/context/IOLocalContextStorage.scala

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ package org.typelevel.otel4s.oteljava.context
1919
import cats.effect.IOLocal
2020
import cats.effect.LiftIO
2121
import cats.effect.MonadCancelThrow
22+
import cats.effect.std.Console
2223
import cats.mtl.Local
24+
import cats.syntax.flatMap._
25+
import cats.syntax.functor._
2326
import io.opentelemetry.context.{Context => JContext}
2427
import io.opentelemetry.context.ContextStorage
2528
import io.opentelemetry.context.Scope
@@ -30,7 +33,7 @@ import org.typelevel.otel4s.context.LocalProvider
3033
* that reflect the state of the backing `IOLocal`. Usage of `Local` and `ContextStorage` methods will be consistent
3134
* and stay in sync as long as effects are threaded properly.
3235
*/
33-
class IOLocalContextStorage(
36+
private class IOLocalContextStorage(
3437
_ioLocal: () => IOLocal[Context],
3538
_unsafeThreadLocal: () => ThreadLocal[Context]
3639
) extends ContextStorage {
@@ -58,9 +61,6 @@ class IOLocalContextStorage(
5861

5962
object IOLocalContextStorage {
6063

61-
private val AgentContextStorageClass =
62-
"io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage"
63-
6464
/** Returns a [[cats.mtl.Local `Local`]] of a [[org.typelevel.otel4s.oteljava.context.Context `Context`]] if an
6565
* [[`IOLocalContextStorage`]] is configured to be used as the `ContextStorage` for the Java otel library.
6666
*
@@ -75,34 +75,34 @@ object IOLocalContextStorage {
7575
* }
7676
* }}}
7777
*/
78-
def localProvider[F[_]: LiftIO](implicit F: MonadCancelThrow[F]): LocalProvider[F, Context] =
78+
def localProvider[F[_]: Console: LiftIO](implicit F: MonadCancelThrow[F]): LocalProvider[F, Context] =
7979
new LocalProvider[F, Context] {
8080
def local: F[Local[F, Context]] =
8181
ContextStorage.get() match {
8282
case storage: IOLocalContextStorage =>
8383
whenPropagationEnabled(storage.local)
8484

85-
case other if other.getClass.getName == AgentContextStorageClass =>
86-
whenPropagationEnabled(agentLocal)
87-
8885
case other =>
89-
F.raiseError(
90-
new IllegalStateException(
91-
"IOLocalContextStorage is not configured for use as the ContextStorageProvider. " +
92-
s"The current storage: ${other.getClass.getName}."
93-
)
94-
)
86+
getAgentLocalContext() match {
87+
case Some(ioLocalJContext) =>
88+
val ioLocal = ioLocalJContext.lens(ctx => Context.wrap(ctx))(_ => c => c.underlying)
89+
val local = LocalProvider.localForIOLocal(ioLocal)
90+
91+
for {
92+
_ <- Console[F].println("IOLocalContextStorage: agent-provided IOLocal is detected")
93+
r <- whenPropagationEnabled(local)
94+
} yield r
95+
96+
case None =>
97+
F.raiseError(
98+
new IllegalStateException(
99+
"IOLocalContextStorage is not configured for use as the ContextStorageProvider. " +
100+
s"The current ContextStorage is: ${other.getClass.getName}"
101+
)
102+
)
103+
}
95104
}
96105

97-
private def agentLocal: Local[F, Context] = {
98-
val ioLocal = IOLocalContextStorageProvider.localContext
99-
val threadLocal = IOLocalContextStorageProvider.threadLocalJContext
100-
101-
registerFiberThreadLocalContext(threadLocal)
102-
103-
LocalProvider.localForIOLocal(ioLocal)
104-
}
105-
106106
private def whenPropagationEnabled[A](whenEnabled: => A): F[A] =
107107
if (IOLocal.isPropagating) {
108108
F.pure(whenEnabled)
@@ -115,8 +115,8 @@ object IOLocalContextStorage {
115115
}
116116
}
117117

118-
/** The method is instrumented by the OTeL Java agent to capture the provided thread local. It must be public.
118+
/** The method is instrumented by the OTeL Java agent to provide the IOLocal managed by agent.
119119
*/
120-
def registerFiberThreadLocalContext(threadLocal: ThreadLocal[JContext]): Unit = ()
120+
private[context] def getAgentLocalContext(): Option[IOLocal[JContext]] = None
121121

122122
}

oteljava/context-storage/src/main/scala/org/typelevel/otel4s/oteljava/context/IOLocalContextStorageProvider.scala

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ import cats.effect.IOLocal
2020
import cats.effect.SyncIO
2121
import cats.effect.unsafe.IORuntime
2222
import cats.syntax.all._
23-
import io.opentelemetry.context.{Context => JContext}
2423
import io.opentelemetry.context.ContextStorage
2524
import io.opentelemetry.context.ContextStorageProvider
2625

2726
object IOLocalContextStorageProvider {
28-
private[context] lazy val localContext: IOLocal[Context] =
27+
private lazy val localContext: IOLocal[Context] =
2928
IOLocal[Context](Context.root)
3029
.syncStep(100)
3130
.flatMap(
@@ -37,7 +36,7 @@ object IOLocalContextStorageProvider {
3736
)
3837
.unsafeRunSync()
3938

40-
private[context] lazy val threadLocalContext: ThreadLocal[Context] =
39+
private lazy val threadLocalContext: ThreadLocal[Context] =
4140
new ThreadLocal[Context] {
4241
private val fiberLocal = localContext.unsafeThreadLocal()
4342

@@ -51,18 +50,6 @@ object IOLocalContextStorageProvider {
5150
if (IORuntime.isUnderFiberContext()) fiberLocal.set(value) else super.set(value)
5251
}
5352

54-
private[context] lazy val threadLocalJContext: ThreadLocal[JContext] =
55-
new ThreadLocal[JContext] {
56-
override def initialValue(): JContext =
57-
JContext.root()
58-
59-
override def get(): JContext =
60-
threadLocalContext.get().underlying
61-
62-
override def set(value: JContext): Unit =
63-
threadLocalContext.set(Context.wrap(value))
64-
}
65-
6653
}
6754

6855
/** SPI implementation for [[`IOLocalContextStorage`]]. */

0 commit comments

Comments
 (0)