Baggage

In OpenTelemetry, Baggage is a mechanism for propagating key-value pairs across service boundaries. It allows applications to attach contextual metadata (e.g., request IDs, user IDs, or debug flags) to distributed traces, ensuring that relevant data flows alongside requests without modifying their payloads.

Baggage is primarily used for:

What is BaggageManager?

BaggageManager is a functional abstraction that provides an interface to manage Baggage. It extends Local[F, Baggage] and can:

How to get the BaggageManager

import cats.effect.IO
import org.typelevel.otel4s.baggage.BaggageManager
import org.typelevel.otel4s.oteljava.OtelJava

OtelJava.autoConfigured[IO]().use { otel4s =>
  val baggageManager: BaggageManager[IO] = otel4s.baggageManager
  IO.println("BaggageManager: " + baggageManager)
}
import cats.effect.IO
import org.typelevel.otel4s.baggage.BaggageManager
import org.typelevel.otel4s.sdk.OpenTelemetrySdk
import org.typelevel.otel4s.sdk.exporter.otlp.autoconfigure.OtlpExportersAutoConfigure

OpenTelemetrySdk
  .autoConfigured[IO](_.addExportersConfigurer(OtlpExportersAutoConfigure[IO]))
  .use { auto =>
    val baggageManager: BaggageManager[IO] = auto.sdk.baggageManager
    IO.println("BaggageManager: " + baggageManager)
  }

How to use BaggageManager

Baggage can be modified exclusively in a scoped-manner.

Reading the current Baggage

def printBaggage(implicit bm: BaggageManager[IO]): IO[Unit] =
  BaggageManager[IO].current.flatMap(b => IO.println(s"Baggage: $b"))

Setting and modifying Baggage

import org.typelevel.otel4s.baggage.Baggage

def withUserId[A](fa: IO[A])(implicit bm: BaggageManager[IO]): IO[A] =
  bm.local(fa)(b => b.updated("user-id", "12345"))

def withScopedBaggage[A](fa: IO[A])(implicit bm: BaggageManager[IO]): IO[A] =
  bm.scope(fa)(Baggage.empty.updated("request-id", "req-abc"))

Retrieving a specific baggage entry

def fetchBaggageEntry(implicit bm: BaggageManager[IO]): IO[Unit] =
  bm.getValue("user-id").flatMap {
    case Some(userId) => IO.println(s"User ID: $userId")
    case None         => IO.println("User ID not found in baggage")
  }