-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
oteljava: add OtelJava.noop
#543
Conversation
oteljava/all/src/main/scala/org/typelevel/otel4s/oteljava/OtelJava.scala
Outdated
Show resolved
Hide resolved
I'm not sure how I feel about this. I'm not convinced that it's necessary, given that |
In some scenarios, For example, when dealing with big and modular apps: class StreamingModule[F[_]: OtelJava]
class ScoringModule[F[_]: OtelJava]
class HttpModule[F[_]: OtelJava] vs: class StreamingModule[F[_]: MeterProvider: TracerProvider: LocalContext]
class ScoringModule[F[_]: MeterProvider: TracerProvider: LocalContext]
class HttpModule[F[_]: MeterProvider: TracerProvider: LocalContext] Also, |
Hi, I'm going to leave my notes here about @NthPortal's question: My use cases:
What you just mentioned is how my code looks like at the moment: for {
noopOpenTelemetry <- IO(OpenTelemetry.noop())
otelJava <- OtelJava.forAsync[IO](noopOpenTelemetry)
} yield ... My problem with this, is that this is in an effect, and I need to call And some side note: And to have a bit of a confession here, I'm not passing around an OtelJava, but a custom case class. This is how my code looks like actually: case class Telemetry(
openTelemetry: OpenTelemetry, // until underlying is not exposed
otel4s: OtelJava[IO], // here for the above reasons
meter: Meter[IO], // because I don't need a provider, I need a meter in my code
tracer: Tracer[IO] // because I don't need a provider, I need a tracer in my code
) Conclusion: if you are not comfortable with the current noop proposal because of that noopLocal I can totally understand that, and I'm okey with the |
With the proposed implementation of the noop instance, you will still need to run private val noopOtelJava: OtelJava[IO] = {
implicit val local: Local[IO, Context] = LocalProvider[IO, Context].local.unsafeRunSync()
OtelJava.noop
} The closest alternative that is currently available (in private val noopOtelJava: OtelJava[IO] = {
implicit val local: Local[IO, Context] = LocalProvider[IO, Context].local.unsafeRunSync()
OtelJava.local(JOpenTelemetry.noop)
} |
if you're using a no-op implementation, what do you need context for? there's no span data in it |
No, if I use a
My classes expect an
When I run my tests, I'd like to pass a noop |
You can implement a custom import io.opentelemetry.context.propagation.{TextMapPropagator => JTextMapPropagator}
import org.typelevel.otel4s.context.propagation.{TextMapGetter, TextMapPropagator, TextMapUpdater}
import org.typelevel.otel4s.oteljava.context.Context
import org.typelevel.otel4s.oteljava.context.propagation.PropagatorConverters._
val customPropagator = new TextMapPropagator[Context] {
val fields: Iterable[String] = List("custom_header") // that's a utility info
def extract[A: TextMapGetter](ctx: Context, carrier: A): Context = ???
def inject[A: TextMapUpdater](ctx: Context, carrier: A): A = ???
}
OtelJava.autoConfigured(
_.addPropagatorCustomizer((t, c) => JTextMapPropagator.composite(t, customPropagator.asJava) )
) But if you use the noop implementation, the propagation will not work. |
a no-op
see
I don't fully understand the details of these, but in general your strategy has the issue that you're trying to get an implementation that performs no operations to do things, which is incorrect. I would say if you just want working context and nothing else, wrapping the Java we can even potentially have our wrappers of the Java † please note that the Scala and Java contexts do not automatically interoperate at this time, and you will need to manually transfer the context at boundaries anyway. the eventual solution to this is #214 |
@fugafree I don't think you really need to wrap it in |
And this is what I want. The propagation code is in my prod code, and sometimes the "backend" telemetry is noop, for tests.
Wow, very nice. Thank you!
I meant that there will be always scenarios, when I will need to get a java To summarize: this seems to be the best way of having a noop otel4s after all:
By having this discussion, I'm perfectly okey with this. If you are comfortable with closing this PR and the issue without merging it, feel free to do so. |
Use cases aside, I see the following pattern:
Following this reasoning, The definition, however, can be different. def noop[F[_]: Applicative: LocalContext]: OtelJava[F] Unfortunately, a user must provide In most cases, a user will end up doing def noop[F[_]: Applicative: LocalContextProvider]: F[OtelJava[F]] Well, you need to evaluate an effect to get a noop instance. On the other hand, everything works out of the box. Another unrelated thought is that you can always use This works fine when you run an application. However, in tests I would prefer an explicit |
I would extend this a bit:
It is also used to reach internal context, because that is the only tool at the moment to
Another thought for
Yes, would be nice, that's why I opened the Issue. Although not very critical. |
this is not quite correct. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I continue to feel dubious about this, but if it serves a need, then let's go for it
Closes #542.