Skip to content

5201 zio interceptor#5203

Draft
cheleb wants to merge 6 commits into
softwaremill:masterfrom
cheleb:5201-zio-interceptor
Draft

5201 zio interceptor#5203
cheleb wants to merge 6 commits into
softwaremill:masterfrom
cheleb:5201-zio-interceptor

Conversation

@cheleb
Copy link
Copy Markdown

@cheleb cheleb commented May 2, 2026

No description provided.

@cheleb cheleb force-pushed the 5201-zio-interceptor branch 2 times, most recently from 3d37fca to 9b9a8a3 Compare May 3, 2026 07:48
@cheleb cheleb force-pushed the 5201-zio-interceptor branch from 9b9a8a3 to 0252534 Compare May 9, 2026 17:05
@cheleb cheleb marked this pull request as ready for review May 10, 2026 14:04
@cheleb cheleb force-pushed the 5201-zio-interceptor branch 2 times, most recently from e16c0cb to 353fea1 Compare May 11, 2026 20:19
//> using dep com.softwaremill.sttp.tapir::tapir-zio-http-server:1.13.18
//> using dep com.softwaremill.sttp.tapir::tapir-swagger-ui-bundle:1.13.18
//> using dep com.softwaremill.sttp.tapir::tapir-zio:1.13.18
//> using dep com.softwaremill.sttp.tapir::tapir-zio-tracing:1.13.18
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, zio-tracing is not yet published, so this will fail in the build. You'll need to comment out the entire file for now, we'll bring it back after a release of an initial version

@adamw
Copy link
Copy Markdown
Member

adamw commented May 13, 2026

Some notes from Claude's review:

  Major issues

  1. OpenTelemetry version downgrade (high risk)

  project/Versions.scala changes openTelemetry from 1.62.0 → 1.61.0. This is a global version used by every otel module (opentelemetry-tracing, otel4s-tracing, metrics, etc.). A downgrade is almost certainly
  unintentional and should be reverted. If 1.62.0 is incompatible with zio-opentelemetry 3.1.15, pin the runtime-telemetry artifact separately rather than rolling back the global version.

  2. Module name / scope mismatch

  The module is in tracing/zio-observability with package sttp.tapir.server.tracing.ziotel, but it spans tracing + metrics + logging. Existing modules separate these (tracing/*, metrics/*). Either:
  - restrict the module to tracing only (matching the directory + package), or
  - move it to a new top-level directory and split into tracing/zio-tracing, metrics/zio-metrics-otel, etc.

  The current placement is misleading and inconsistent with project conventions.

  3. Wrong package declaration in the test

  ZIOtelTracingTest.scala:1 declares package sttp.tapir.server.tracing.otel4s but imports from sttp.tapir.server.tracing.ziotel. Copy-paste error — fix to ziotel.

  4. Shared mutable carrier across requests (likely concurrency bug)

  ZIOtelTracingConfig holds a single IncomingContextCarrier[mutable.Map[String, String]]. ZIOtelTracing.apply passes config.carrier directly into tracing.extractSpanUnsafe(...) for every request. If the carrier is
  backed by a mutable map populated from headers per call, concurrent requests will race on it. The carrier should be constructed per-request from the request's headers, not held in config.

  5. Coupled bootstrap forces tracing + metrics + logging

  ZIOtelBase.otelLayer always combines tracing, logging, metrics, and Java17 runtime telemetry. Users who only want tracing must override otelLayer entirely and re-implement the wiring. Split into smaller composable
  layers (e.g. tracingLayer, metricsLayer, loggingLayer) and let users pick.

  serverOptions similarly hard-codes CORSInterceptor.default and defaultServerLog, which doesn't belong in an observability helper at all.

  6. Naming inconsistencies and typos

  - OltpEndpoint, oltpEnvVar, globalOltpEndpointEnvVar — should be Otlp (OpenTelemetry Protocol).
  - File name ZIOObservabiltyExample.skip — missing 'i' in "Observability".
  - setSpanAttibutes (ZIOtelTracing.scala:837) — missing 'r' in "Attributes".
  - Ovverride (example file comment).
  - Scaladoc in ZIOtelTracing.scala:686-707 refers to ZIOpenTelemetryTracing and Otel4z, but the class is ZIOtelTracing (otel4s pattern was copied without updating the docs).
  - Trait file is ZIOpenTelemetry.scala but most other types use the ZIOtel* prefix. Pick one prefix and use it consistently.

  7. Scala 2 / Scala 3 trait asymmetry

  Scala 3 trait takes (resourceName, oltpEnvVar) as constructor params; Scala 2 version has them as abstract/def with a default for oltpEnvVar only. The test files reflect this (Scala 2 overrides resourceName; Scala 3
  passes as ctor arg). The @param name scaladoc is wrong on both sides. Either unify the API (abstract defs on both) or document the divergence.

  8. Thin test coverage

  Only one test (ZIOtelTracingTest) that asserts getFinishedSpanItems.isEmpty() is false. No assertions on:
  - span name / HTTP_ROUTE / status code attributes
  - error path (5xx + thrown exception)
  - context propagation (W3C traceparent header in → parent span)
  - requestAttributes defaults

  Compare against Otel4sTracingTest, which exercises each of these. At a minimum, mirror those scenarios.

  Minor issues

  - ZIOtelTracing.scala:819-822 — the block
  span
    .updateName(name)
  span.setAllAttributes(attributes)
  - is confusing formatting; the chained .updateName(name) result is dropped and the next line starts a new statement. Just write span.updateName(name); span.setAllAttributes(attributes).
  - ZIOtelTracingConfig.scala:1006 — response.code.code.toLong.asInstanceOf[java.lang.Long] — use java.lang.Long.valueOf(...) instead of asInstanceOf.
  - opentelemetry-runtime-telemetry-java17 is alpha and JVM 17+ only. withRuntimeTelemetry: Boolean = true will silently fail on JDK 11. Default to false, or move it behind an explicit opt-in helper.
  - MeterProvider.stdout and TracerProvider.stdout/fluentbit are defined but unused. Drop them unless tests/examples cover them.
  - Trailing whitespace and blank lines throughout (e.g. ZIOtelBase.scala:497-505, :546-551, :579). Run scalafmt.
  - Example file is acknowledged as needing .skip until zio-tracing is published (adamw's PR comment). Fine — but the inline using dep ... tapir-zio-tracing:1.13.18 reference doesn't match the actual module name
  tapir-zio-observability.
  - TracerProvider.grpc etc. accept envVar: String, globalOltpEnvVar: String as positional String parameters — easy to swap accidentally. A small case class (e.g. OtlpEndpointConfig) would be safer.
  - Scaladoc @param name appears on traits that have no name param. Remove or fix.

Regarding the "observability" / tracing module naming - there is already a zio-metrics module (https://tapir.softwaremill.com/en/latest/server/observability.html#zio-metrics). How would it relate to what's provided here? Is it at all possible to have an only-tracing module? Or maybe we should combine them?

cheleb and others added 6 commits May 13, 2026 13:29
- Renamed zioTracing to zioObservability in build.sbt and related project files.
- Added ZIOObservabiltyExample demonstrating ZIO with Tapir and OpenTelemetry for tracing.
- Introduced ZIOpenTelemetry trait for OpenTelemetry integration.
- Created LoggerProvider, MeterProvider, and TracerProvider for handling logging, metrics, and tracing respectively.
- Implemented OltpEndpoint trait for managing OTLP gRPC endpoint configurations.
- Developed ZIOtelBase and ZIOtelLayer for setting up OpenTelemetry layers.
- Added ZIOtelTracing and ZIOtelTracingConfig for configuring tracing behavior.
- Created test applications for verifying ZIO Observability functionality.
- Updated tests to validate tracing behavior with in-memory span exporter.
Integrate OpenTelemetry metrics into the ZIO observability layer by:
- Adding `opentelemetryMetrics` dependency to `zio-observability` project.
- Configuring `ZIOtelBase` to include `OpenTelemetry.metrics` and `OpenTelemetry.zioMetrics` in the layer stack.
- Adding `OpenTelemetryMetrics` interceptor to the ZioHttpServerOptions.
- Adding a new ZIO OpenTelemetry observability example.
Add a new `.skip` example demonstrating how to integrate ZIO with Tapir and OpenTelemetry for tracing.
…example

Update the `ZIOtelBase` trait to include `Meter` in its environment and ensure the bootstrap layer correctly provides both tracing and metrics. Also, update the ZIO observability example to reflect these changes, including updated imports and a more detailed explanation of the server options.
@cheleb cheleb marked this pull request as draft May 13, 2026 11:30
@cheleb cheleb force-pushed the 5201-zio-interceptor branch from f8b2ff7 to 4636a20 Compare May 13, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants