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?

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

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

API reference

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