otel4s
otel4s provides OpenTelemetry APIs and integrations for Scala, built on Cats Effect. Use it to instrument applications and libraries with traces, metrics, and logs while keeping the telemetry backend explicit.
The core APIs support Scala 2.13 and Scala 3 on the JVM, Scala.js, and Scala Native. This repository also provides the
JVM-only otel4s-oteljava backend, which implements those APIs with OpenTelemetry Java.
Why otel4s?
- Designed for low overhead. Compile-time techniques reduce runtime allocations, while no-op providers let instrumented code run without an SDK or exporter.
- Modular. Applications and libraries can depend only on the signals they use and choose a telemetry backend separately. See Modules and module families.
- Cross-platform. The core APIs support Scala 2.13 and Scala 3 on the JVM, Scala.js, and Scala Native.
- Built for testing. In-memory testkits collect traces, metrics, and logs and provide structured expectation APIs without requiring an external collector. See Testkit.
Quick start
For a JVM application, add the OpenTelemetry Java backend, OTLP exporter, and autoconfiguration extension.
Add these settings to build.sbt:
libraryDependencies ++= Seq(
"org.typelevel" %% "otel4s-oteljava" % "1.1.0",
"io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.66.0" % Runtime,
"io.opentelemetry" % "opentelemetry-sdk-extension-autoconfigure" % "1.66.0" % Runtime
)
javaOptions += "-Dotel.java.global-autoconfigure.enabled=true"
Add these directives to the *.scala file:
//> using dep "org.typelevel::otel4s-oteljava:1.1.0"
//> using dep "io.opentelemetry:opentelemetry-exporter-otlp:1.66.0"
//> using dep "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure:1.66.0"
//> using javaOpt "-Dotel.java.global-autoconfigure.enabled=true"
Create a tracer and meter, then record a span and counter measurement:
import cats.effect.{IO, IOApp}
import org.typelevel.otel4s.oteljava.OtelJava
object Main extends IOApp.Simple {
def run: IO[Unit] =
OtelJava.autoConfigured[IO]().use { otel4s =>
for {
tracer <- otel4s.tracerProvider.get("com.example.app")
meter <- otel4s.meterProvider.get("com.example.app")
counter <- meter.counter[Long]("hello.count").create
_ <- tracer.span("hello").surround {
counter.inc().flatMap(_ => IO.println("hello"))
}
} yield ()
}
}
For instrument types and recording patterns, see Record application metrics.
OtelJava.autoConfigured creates an isolated, non-global SDK instance and uses OpenTelemetry Java's OTLP defaults
unless you configure them. Follow Set up otel4s in a JVM application to set the service name and exporter
endpoint and verify the exported span.
Start here
- To configure a JVM application and export telemetry, follow Set up otel4s in a JVM application.
- To instrument a library without choosing a backend for its users, see Modules and module families.
- To use a backend on Scala.js or Scala Native, see the separate otel4s SDK project.
Guides
| Task | Guide |
|---|---|
| Configure the OpenTelemetry Java backend | JVM setup |
| Create spans and propagate trace context | Tracing |
| Record application and runtime metrics | Metrics |
| Bridge application logs into OpenTelemetry | Logs |
| Use generated OpenTelemetry attributes and metric specs | Semantic conventions |
| Assert exported telemetry in tests | Testkit |
Understand otel4s
- Modules and module families explains how the API, backend, instrumentation, semantic convention, and testkit artifacts fit together.
- The JVM backend explains when to use
OtelJava.autoConfiguredorOtelJava.global. - How otel4s context propagation works describes the tracing context model used by the core APIs.
- Semantic conventions and stability describes the stable and experimental semantic convention modules.
API reference
- Tracing API
- Metrics API
- Logs API
- Cross-service trace propagation
- Semantic conventions
- OpenTelemetry Java testkit
To run instrumented code without an SDK or exporter, provide a no-op tracer or no-op meter.
Published modules
otel4s 1.0 establishes the compatibility baseline for the modules published from this repository. Artifacts that
remain unstable are explicitly marked, including the *-experimental semantic convention modules.
| Module family | JVM | Scala Native | Scala.js |
|---|---|---|---|
otel4s-core* |
✅ | ✅ | ✅ |
otel4s-semconv* |
✅ | ✅ | ✅ |
otel4s-instrumentation-* |
✅ | ✅ | ✅ |
otel4s-oteljava* |
✅ | ❌ | ❌ |
Examples and integrations
- Run otel4s locally with Jaeger and Docker or Grafana.
- Export traces and metrics to Honeycomb or Dash0.
- Find integrations for other Typelevel libraries on the Ecosystem page.