Releases: typelevel/otel4s
v0.15.1
Note
This release is binary compatible with 0.15.0.
Warning
If you use opentelemetry-java 1.59.0, please use otel4s 0.15.1.
Key changes
Support for complex attributes
You can use AnyValue directly with Attribute, allowing nested and structured values:
import org.typelevel.otel4s.AnyValue
import org.typelevel.otel4s.Attribute
val anyValue: AnyValue = AnyValue.map(
Map(
"nested-string" -> AnyValue.string("string"),
"nested-long" -> AnyValue.long(123L)
)
)
val attribute = Attribute("anyValueAttribute", anyValue)This change is mandated by the OpenTelemetry specification.
Semantic Conventions 1.39.0
Semantic conventions are regenerated using version 1.39.0 of the OpenTelemetry semconv specification.
What's Changed
Core
Semantic Conventions
- Update opentelemetry-semconv to 1.39.0 by @typelevel-steward[bot] in #1170
Documentation
- Added Dash0 example by @CodingFabian in #1166
Dependencies
- Update scalafmt-core to 3.10.5 by @typelevel-steward[bot] in #1169
- flake.lock: Update by @typelevel-steward[bot] in #1168
- Update scalafmt-core to 3.10.6 by @typelevel-steward[bot] in #1171
New Contributors
- @CodingFabian made their first contribution in #1166
Full Changelog: v0.15.0...v0.15.1
v0.15.0
We are happy to announce the 0.15.0 release.
Note
The otel4s-sdk* modules have been moved to a new repository and now have their own release cycle.
Warning
There are several minor binary- and source-breaking changes. Primarily around BaggageManager and *Testkit builders. Several deprecated methods were also removed.
Key changes
1. SDK modules moved to a separate repository
The otel4s-sdk modules have been moved out of this repository. The primary reason for this is to allow other libraries, such as fs2 and http4s, to use otel4s directly.
2. BaggageManager.noop
BaggageManager now exposes a noop implementation. This is particularly useful in tests when you don't care about baggage propagation.
val baggageManager: BaggageManager[IO] = BaggageManager.noop3. Span finalizer API updates
SpanFinalizer internal classes are now private, since they were never intended to be public.
There are also new combinators, such as updateName, addEvent, or addLink.
4. Tracer.withCurrentSpanOrNoop
There is a new withCurrentSpanOrNoop convenience method on Tracer to simplify working with optional span context.
Before:
Tracer[IO].currentSpanOrNoop.flatMap(_.addAttribute(Attribute("key", "value")))After:
Tracer[IO].withCurrentSpanOrNoop(_.addAttribute(Attribute("key", "value")))5. Attribute.From for semantic convention values
Semantic convention *Value classes now provide Attribute.From instances, making it easier to build attributes from semantic convention values.
Before:
val attribute: Attribute[String] = NetworkTransport(NetworkTransportValue.Tcp.value)After:
val attribute: Attribute[String] = NetworkTransport(NetworkTransportValue.Tcp)6. *Testkit builders
Testkit classes now use builders instead of static create/inMemory methods. This makes testkits easier to evolve without expanding the public API surface, and makes configuration more uniform across traces, metrics, and logs.
Old style (deprecated/removed):
TracesTestkit.inMemory[IO](
customize = (b: io.opentelemetry.sdk.trace.SdkTracerProviderBuilder) => b, /* your edits */
textMapPropagators = List(/* propagators */)
)New style:
TracesTestkit
.builder[IO]
.addTracerProviderCustomizer(b => b /* your edits */)
.withTextMapPropagators(List(/* propagators */))
.buildOr via the new inMemory overload that customizes the builder:
TracesTestkit.inMemory[IO](
_.addTracerProviderCustomizer(b => b /* your edits */)
.withTextMapPropagators(List(/* propagators */))
)This is the same pattern across oteljava LogsTestkit, MetricsTestkit, TracesTestkit, and OtelJavaTestkit: you now customize a Builder[F] via add...Customizer(...) methods, and you set exporters/readers via withInMemory...(...) on the builder rather than passing fromInMemory/exporter style parameters.
What's Changed
Core
- core-common: add
BaggageManager.noopby @iRevive in #1094 - core-trace: make
SpanFinalizerinner classes private, add missing API by @iRevive in #1159 - core-trace: add
withCurrentSpanOrNooputility toTracerby @iRevive in #1160 - Add builders for
*Testkitby @iRevive in #1126
Semantic Conventions
Documentation
- docs: add documentation for the
Logsmodule by @iRevive in #1119 - Add mention of
fs2-queuesotel4s integration by @satabin in #1132 - docs: add note where SDK modules were moved by @iRevive in #1155
- docs: add semantic conventions documentation by @iRevive in #1161
Dependencies
- Update opentelemetry-javaagent to 2.24.0 by @typelevel-steward[bot] in #1157
- Update opentelemetry-instrumentation-annotations to 2.24.0 by @typelevel-steward[bot] in #1156
- Update opentelemetry-api, ... to 1.58.0 by @typelevel-steward[bot] in #1151
- Update scalafmt-core to 3.10.4 by @typelevel-steward[bot] in #1158
- Update scala-library, scala-reflect to 2.13.18 by @typelevel-steward[bot]in #1137
- Update scala-library to 2.12.21 by @typelevel-steward[bot] in #1142
- Update http4s-circe, http4s-dsl, ... to 0.23.33 by @typelevel-steward[bot] in #1127
- Update pekko-http to 1.3.0 by @typelevel-steward[bot] in #1121
- Update pekko-stream to 1.4.0 by @typelevel-steward[bot] in #1143
- Update opentelemetry-proto to 1.9.0-alpha by @typelevel-steward[bot] in #1131
- Update sbt-typelevel, ... to 0.8.4 by @typelevel-steward[bot] in #1147
- Update sbt-scalajs, scalajs-compiler, ... to 1.20.2 by @typelevel-steward[bot] in #1152
- Update sbt-javaagent to 0.2.0 by @typelevel-steward[bot] in #1141
- flake.lock: Update by @typelevel-steward[bot] in #1149
Uncategorized
- Update otel4s-opentelemetry-javaagent version by @iRevive in #1136
- Show Scaladex version badge by @iRevive in #1154
New Contributors
Full Changelog: v0.14.0...v0.15.0
v0.14.0
We are happy to announce the 0.14.0 release.
Warning
While most changes are source-compatible, there are a few breaking changes across multiple modules.
Please review carefully before upgrading.
Key changes
1. Sealed interfaces
We have sealed many of the core interfaces. There are two sides of this decision:
- Cons: This makes it harder for third-party libraries to extend otel4s directly.
- Pros: It gives us much more flexibility to evolve the public API safely over time.
This change is especially important as we look ahead to the 1.0 release. The OpenTelemetry specification is still actively evolving, and sealing interfaces allows us
to add new methods without breaking binary compatibility.
We know this is a trade-off. If feedback shows this experiment is not working well, we may unseal some interfaces in the future.
See the reasoning behind this change: #1029.
2. Attributes.Make
We have introduced the Attributes.Make typeclass to make it easier to turn your own domain values into Attributes.
For example:
case class User(id: Long, group: String)
implicit val userAttributesMake: Attributes.Make[User] =
user => Attributes(Attribute("user.id", user.id), Attribute("user.group", user.group))
// now you can directly create attributes from your User
val attributes: Attributes = Attributes.from(User(1L, "admin"))
// use it naturally in spans:
Tracer[IO].span("find-user", Attributes.from(user))This is especially useful when you want to consistently record attributes for domain entities such as users, orders, sessions, or request metadata.
3. mapK renamed to liftTo
As preparation for #1001, all mapK methods have been renamed to liftTo.
The change is binary-compatible. Old usages still compile, but you will see a deprecation warning pointing you to the new liftTo method.
This should make migrations smooth.
4. New Logging module
We now provide an experimental logging module:
- Spec: https://opentelemetry.io/docs/specs/otel/logs/
- Modules:
otel4s-logs,otel4s-oteljava-logs,otel4s-sdk-logs,otel4s-sdk-exporter-logs
Note
The logging module is only for bridging logs from other logging frameworks into OpenTelemetry.
It is not a replacement for a full logging API.
Examples:
- A library such as scribe or log4cats can use the otel4s-logs API to export logs over the OpenTelemetry protocol.
- OpenTelemetry-Java bindings are provided in
otel4s-oteljava-logs. - For Scala.js and Scala Native,
otel4s-sdk-logsoffers a pure Scala implementation.
This closes an important gap in the ecosystem, allowing structured logs to be exported alongside metrics and traces.
Check out the documentation for more details.
5. New AWS EKS resource detector
The detector provides EKS-specific resource attributes when running on AWS EKS.
Check out the documentation for more details.
Kudos to @brbrown25.
6. New otel4s-oteljava-context-storage-testkit module
The opentelemetry-sdk-testing uses SettableContextStorage as a context storage, which is not compatible with the IOLocalContextStorage.
To address this, you can use the IOLocalTestContextStorage in your tests:
import cats.effect.IO
import org.typelevel.otel4s.oteljava.context.LocalContextProvider
import org.typelevel.otel4s.oteljava.testkit.context.IOLocalTestContextStorage
implicit val localContextProvider: LocalContextProvider[IO] = IOLocalTestContextStorage.localProvider[IO]Check out the documentation for more details.
Kudos to @AlixBa.
7. New fromInMemory builder for *Testkit objects
In some cases, a program can rely on both Java instrumentation and Scala instrumentation.
To make it easier to test such programs, we have added a fromInMemory method to all *Testkit objects.
Check out the documentation for more details.
Kudos to @AlixBa.
Acknowledgements
Big thanks to @NthPortal for thorough reviews and valuable feedback during this cycle. 🙌
What's Changed
Core
- logs: add
core-logsmodule by @iRevive in #1013 - core-common: add
AnyValueby @iRevive in #1009 - core-logs: add Severity by @iRevive in #1015
- Define
hashCodeaslazy valby @c0d33ngr in #1019 - core-common: add
Attributes.Makeby @iRevive in #1023 - core-logs: add LogRecordBuilder by @iRevive in #1018
- docs: update scaladoc example by @iRevive in #1034
- core-logs: add
LoggerProvider,LoggerBuilder, andLoggerby @iRevive in #1030 - Rename most
mapKmethods toliftToby @NthPortal in #1002 - Seal public traits by @iRevive in #1037
- sdk-exporter-logs: add
LogsProtoEncoderby @iRevive in #1057 - Add
otel4s-oteljava-logsmodule by @iRevive in #1038 - Wire all logs modules together by @iRevive in #1077
- core-logs: add
Logger.Metaby @iRevive in #1084 - Refactor
InstrumentMetaby @iRevive in #1085
SDK
- sdk-logs: add
LogRecordDataby @iRevive in #1040 - Update opentelemetry-semconv to 1.37.0 by @typelevel-steward[bot] in #1051
- sdk-logs: add
LogRecordLimitsby @iRevive in #1041 - sdk-logs: add
LogRecordLimitsAutoConfigureby @iRevive in #1058 - sdk-logs: add
LogRecordExporterby @iRevive in #1056 - sdk-logs: add
ConsoleLogRecordExporterby @iRevive in #1061 - sdk-logs: add
LogRecordProcessorby @iRevive in #1055 - sdk-logs: Evaluate multiple processors sequentially by @iRevive in #1068
- sdk-logs: Add
SimpleLogRecordProcessorby @iRevive in #1067 - sdk-logs: Add
BatchLogRecordProcessorby @iRevive in #1066 - sdk-logs: Add
SdkLogRecordBuilderby @iRevive in #1069 - sdk-logs: Add
LogRecordExportersAutoConfigureby @iRevive in #1071 - sdk-logs: Add
SdkLoggerProvider,SdkLoggerBuilder, andSdkLoggerby @iRevive in #1072 - sdk-logs-testkit: Add
LogsTestkitby @iRevive in #1070 - sdk-logs: add
BatchLogRecordProcessorAutoConfigureby @iRevive in #1073 - sdk-logs: add
LoggerProviderAutoConfigurerby @iRevive in #1075 - sdk-logs: add
SdkLogsby @iRevive in #1076 - Add
otel4s-sdk-logsmodule by @iRevive in #1039
SDK exporter
- sdk-exporter: update OTLP exporter docs by @iRevive in #1042
- sdk-exporter-logs: add
OtlpLogRecordExporterby @iRevive in #1063 - Metrics SDK: Ignore empty and annotations unit by @lenguyenthanh in #1089
SDK Contrib AWS
- feat(AwsEksDetector): Adding in functionality for the AWSEksDetector similar to the java implementation. #783. by @brbrown25 in #1096
- chore(DockerHelper): switching to Concurrent instead of Async. #783. by @brbrown25 in #1098
Semantic Conventions
OtelJava
- oteljava: add
TracesTestkit#resetSpansby @iRevive in #1028 - oteljava-logs-test: add
LogsTestkitby @iRevive in #1064 - unwrap IOLocalContextStorage from SettableContextStorageProvider in t… by @AlixBa in #996
- add fromInMemory on Testkits by @AlixBa in #1081
Build
- build: do not upload JS and SN artifacts by @iRevive in #1093
- sdk-exporter: try to address flaky tests by @iRevive in #1114
Documentation
- docs: add sttp and tapir to the ecosystem by @iRevive in #1024
- Use Resource.fromAutoCloseable in docs by @mzuehlke in #1033
- docs: add otel4s Java Agent example by @iRevive in #1044
- docs: add logs module configuration details by @iRevive in #1074
- Update exporter property key from 'otlp' to 'otel' by @lenguyenthanh in https://github.com/typelevel/otel4s/p...
v0.14.0-RC3
What's Changed
Core
SDK exporter
- Metrics SDK: Ignore empty and annotations unit by @lenguyenthanh in #1089
Documentation
- Update exporter property key from 'otlp' to 'otel' by @lenguyenthanh in #1086
- Correct disabled TimerHeapConfig in docs by @lenguyenthanh in #1087
Dependencies
- flake.lock: Update by @typelevel-steward[bot] in #1092
Uncategorized
Full Changelog: v0.14.0-RC2...v0.14.0-RC3
v0.13.2
What's Changed
SDK Metrics Exporter
- Metrics SDK: Ignore empty and annotations unit by @lenguyenthanh in #1089
Full Changelog: v0.13.1...v0.13.2
v0.14.0-RC2
What's Changed
OtelJava
- unwrap IOLocalContextStorage from SettableContextStorageProvider in t… by @AlixBa in #996
- add fromInMemory on Testkits by @AlixBa in #1081
Documentation
Dependencies
- Update opentelemetry-javaagent to 2.20.0 by @typelevel-steward[bot] in #1080
- Update opentelemetry-instrumentation-annotations to 2.20.0 by @typelevel-steward[bot] in #1079
Uncategorized
Full Changelog: v0.14.0-RC1...v0.14.0-RC2
v0.14.0-RC1
We are happy to announce the first candidate of the 0.14.0 release.
Warning
While most changes are source-compatible, there are a few binary-breaking changes across multiple modules.
Please review carefully before upgrading.
Key changes
1. Sealed interfaces
We have sealed many of the core interfaces. There are two sides of this decision:
- Cons: This makes it harder for third-party libraries to extend otel4s directly.
- Pros: It gives us much more flexibility to evolve the public API safely over time.
This change is especially important as we look ahead to the 1.0 release.
The OpenTelemetry specification is still actively evolving, and sealing interfaces allows us to add new methods without breaking binary compatibility.
We know this is a trade-off. If feedback shows this experiment is not working well, we may unseal some interfaces in the future.
See the reasoning behind this change: #1029.
2. Attributes.Make
We have introduced the Attributes.Make typeclass to make it easier to turn your own domain values into Attributes.
For example:
case class User(id: Long, group: String)
implicit val userAttributesMake: Attributes.Make[User] =
user => Attributes(Attribute("user.id", user.id), Attribute("user.group", user.group))
// now you can directly create attributes from your User
val attributes: Attributes = Attributes.from(User(1L, "admin"))
// use it naturally in spans:
Tracer[IO].span("find-user", Attributes.from(user))This is especially useful when you want to consistently record attributes for domain entities such as users, orders, sessions, or request metadata.
3. mapK renamed to liftTo
As preparation for #1001, all mapK methods have been renamed to liftTo.
The change is binary-compatible. Old usages still compile, but you will see a deprecation warning pointing you to the new liftTo method.
This should make migrations smooth.
4. New Logging module
Note
The logging module only for bridging logs from other logging frameworks into OpenTelemetry.
It is not a replacement for a full logging API.
We now provide an experimental logging module:
- Spec: https://opentelemetry.io/docs/specs/otel/logs/
- Modules:
otel4s-logs,otel4s-oteljava-logs,otel4s-sdk-logs,otel4s-sdk-exporter-logs
Examples:
- A library such as scribe or log4cats can use the
otel4s-logsAPI to export logs over the OpenTelemetry protocol. - OpenTelemetry-Java bindings are provided in
otel4s-oteljava-logs. - For Scala.js and Scala Native,
otel4s-sdk-logsoffers a pure Scala implementation.
This closes an important gap in the ecosystem, allowing structured logs to be exported alongside metrics and traces.
Acknowledgements
Big thanks to @NthPortal for thorough reviews and valuable feedback during this cycle. 🙌
What's Changed
Core
- logs: add
core-logsmodule by @iRevive in #1013 - core-common: add
AnyValueby @iRevive in #1009 - core-logs: add Severity by @iRevive in #1015
- Define
hashCodeaslazy valby @c0d33ngr in #1019 - core-common: add
Attributes.Makeby @iRevive in #1023 - core-logs: add LogRecordBuilder by @iRevive in #1018
- docs: update scaladoc example by @iRevive in #1034
- core-logs: add
LoggerProvider,LoggerBuilder, andLoggerby @iRevive in #1030 - Rename most
mapKmethods toliftToby @NthPortal in #1002 - Seal public traits by @iRevive in #1037
- sdk-exporter-logs: add
LogsProtoEncoderby @iRevive in #1057 - Add
otel4s-oteljava-logsmodule by @iRevive in #1038 - Wire all logs modules together by @iRevive in #1077
SDK
- sdk-logs: add
LogRecordDataby @iRevive in #1040 - sdk-logs: add
LogRecordLimitsby @iRevive in #1041 - sdk-logs: add
LogRecordLimitsAutoConfigureby @iRevive in #1058 - sdk-logs: add
LogRecordExporterby @iRevive in #1056 - sdk-logs: add
ConsoleLogRecordExporterby @iRevive in #1061 - sdk-logs: add
LogRecordProcessorby @iRevive in #1055 - sdk-logs: Evaluate multiple processors sequentially by @iRevive in #1068
- sdk-logs: Add
SimpleLogRecordProcessorby @iRevive in #1067 - sdk-logs: Add
BatchLogRecordProcessorby @iRevive in #1066 - sdk-logs: Add
SdkLogRecordBuilderby @iRevive in #1069 - sdk-logs: Add
LogRecordExportersAutoConfigureby @iRevive in #1071 - sdk-logs: Add
SdkLoggerProvider,SdkLoggerBuilder, andSdkLoggerby @iRevive in #1072 - sdk-logs-testkit: Add
LogsTestkitby @iRevive in #1070 - sdk-logs: add
BatchLogRecordProcessorAutoConfigureby @iRevive in #1073 - sdk-logs: add
LoggerProviderAutoConfigurerby @iRevive in #1075 - sdk-logs: add
SdkLogsby @iRevive in #1076 - Add
otel4s-sdk-logsmodule by @iRevive in #1039
SDK exporter
- sdk-exporter: update OTLP exporter docs by @iRevive in #1042
- sdk-exporter-logs: add
OtlpLogRecordExporterby @iRevive in #1063
Semantic Conventions
OtelJava
- oteljava: add
TracesTestkit#resetSpansby @iRevive in #1028 - oteljava-logs-test: add
LogsTestkitby @iRevive in #1064
Documentation
- docs: add sttp and tapir to the ecosystem by @iRevive in #1024
- Use Resource.fromAutoCloseable in docs by @mzuehlke in #1033
- docs: add otel4s Java Agent example by @iRevive in #1044
Dependencies
- Update cats-effect, cats-effect-kernel, ... to 3.6.3 by @typelevel-steward[bot] in #1022
- Update opentelemetry-instrumentation-annotations to 2.19.0 by @typelevel-steward[bot] in #1045
- Update opentelemetry-javaagent to 2.19.0 by @typelevel-steward[bot] in #1046
- Update opentelemetry-semconv to 1.37.0 by @typelevel-steward[bot] in #1051
- flake.lock: Update by @typelevel-steward[bot] in #1052
- Update opentelemetry-proto to 1.8.0-alpha by @typelevel-steward[bot] in #1054
- Update pekko-stream to 1.2.0 by @typelevel-steward[bot] in #1053
- Update fs2-core, fs2-io, fs2-scodec to 3.12.2 by @typelevel-steward[bot] in #1060
- Update opentelemetry-api, ... to 1.54.0 by @typelevel-steward[bot] in #1062
- Update sbt, scripted-plugin to 1.11.6 by @typelevel-steward[bot] in #1065
New Contributors
Full Changelog: v0.13.1...v0.14.0-RC1
v0.13.1
What's Changed
SDK
Documentation
Dependencies
- flake.lock: Update by @typelevel-steward in #1004
- Update opentelemetry-instrumentation-annotations to 2.17.0 by @typelevel-steward in #1003
- Update sbt, scripted-plugin to 1.11.3 by @typelevel-steward in #1005
- Update cats-effect, cats-effect-kernel, ... to 3.6.2 by @typelevel-steward in #1006
Full Changelog: v0.13.0...v0.13.1
v0.13.0
We are happy to announce the 0.13.0 release. It brings some UX improvements and new features.
Warning
There are several binary breaking changes core and sdk modules.
New features
1. Redesigned BaggageManager
The BaggageManager no longer extends the cats.mtl.Local. Some methods are deprecated to ease the migration.
2. Dynamic InstrumentMeta
The change introduces two implementations of InstrumentMeta to align with OpenTelemetry's specification, allowing instruments to reflect their enabled or disabled status dynamically.
InstrumentMeta.Dynamic uses an effectful F[Boolean] for runtime checks, while InstrumentMeta.Static retains a fixed Boolean for simpler cases like Span.
What's Changed
Core
- Fix
KindTransformerinstances by @NthPortal in #979 - Redesign
BaggageManagerby @NthPortal in #974 - trace: make SpanBuilder stack safe by @iRevive in #990
- Dynamic instrument meta (enabled/disabled status) by @iRevive in #963
SDK
- SpanBuilder: chain modifyState functions by @iRevive in #965
- sdk: move
LimitedDatato sdk-common by @iRevive in #992 - sdk-trace: use
TracerProvider.noopwhen span processors aren't configured by @iRevive in #991 - sdk: move
TraceContextto sdk-common by @iRevive in #993 - Allocate noop meter instruments only once by @AlixBa in #977
Semantic Conventions
- Update opentelemetry-semconv to 1.34.0 by @typelevel-steward in #988
Dependencies
- Update munit-cats-effect to 2.1.0 by @typelevel-steward in #952
- Update cats-effect, cats-effect-kernel, ... to 3.6.1 by @typelevel-steward in #956
- Update scala3-library, ... to 3.3.6 by @typelevel-steward in #966
- Update pekko-http to 1.2.0 by @typelevel-steward in #972
- Update opentelemetry-instrumentation-annotations to 2.16.0 by @typelevel-steward in #970
- Update opentelemetry-javaagent to 2.16.0 by @typelevel-steward in #971
- Update opentelemetry-proto to 1.7.0-alpha by @typelevel-steward in #975
- Update opentelemetry-api, ... to 1.51.0 by @typelevel-steward in #985
- flake.lock: Update by @typelevel-steward in #978
- Update sbt-typelevel, ... to 0.8.0 by @typelevel-steward in #981
- Update sbt, scripted-plugin to 1.11.2 by @typelevel-steward in #987
- Update sbt-protoc to 1.0.8 by @typelevel-steward in #984
- Update pekko-stream to 1.1.4 by @typelevel-steward in #989
Uncategorized
Full Changelog: v0.12.0...v0.13.0
v0.12.0
We are happy to announce the 0.12.0 release. It brings some UX improvements and new features.
Warning
There are multiple binary breaking changes across modules.
This version relies on new functionality from Cats Effect 3.6.0, such as IORuntimeMetrics.
New features
1. BaggageManager
BaggageManager is a functional abstraction that provides an interface to manage Baggage.
Documentation: https://typelevel.org/otel4s/instrumentation/baggage.html
Reading the current Baggage:
import org.typelevel.otel4s.baggage.{Baggage, BaggageManager}
def printBaggage(implicit bm: BaggageManager[IO]): IO[Unit] =
BaggageManager[IO].current.flatMap(b => IO.println(s"Baggage: $b"))Setting and modifying 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")
}2. Attribute.From
Allows creating an attribute value from an arbitrary type:
case class UserId(id: Int)
implicit val userIdFrom: Attribute.From[UserId, Long] =
_.id.toLong
val userIdKey = AttributeKey[Long]("user.id")
val attribute: Attribute[Long] = userIdKey(UserId(1))
val attribute: Attribute[Long] = Attribute.from(userIdKey, UserId(1))
val attribute: Attribute[Long] = Attribute.from("user.id", UserId(1))3. Attribute.Make
Allows creating an attribute from an arbitrary type:
case class UserId(id: Int)
implicit val userIdFrom: Attribute.From[UserId, Long] =
_.id.toLong
implicit val userIdMake: Attribute.Make[UserId, Long] =
Attribute.Make.const("user.id")
// "user.id=1"
val attribute: Attribute[Long] = Attribute.from(UserId(1))Before:
def findUser(userId: UserId): F[Unit] =
Tracer[F].span("findUser", Attribute("user.id", userId.id.toLong))After:
def findUser(userId: UserId): F[Unit] =
Tracer[F].span("findUser", Attribute.from(userId))4. Cats Effect IO Runtime metrics
Documentation: https://typelevel.org/otel4s/instrumentation/metrics-cats-effect-io-runtime.html.
Configure the build.sbt:
libraryDependencies ++= Seq(
"org.typelevel" %%% "otel4s-instrumentation-metrics" % "0.12.0"
)Use IORuntimeMetrics.register to register collectors:
import cats.effect._
import org.typelevel.otel4s.instrumentation.ce.IORuntimeMetrics
import org.typelevel.otel4s.metrics.MeterProvider
import org.typelevel.otel4s.trace.TracerProvider
import org.typelevel.otel4s.oteljava.OtelJava
object Main extends IOApp.Simple {
def run: IO[Unit] =
OtelJava.autoConfigured[IO]().use { otel4s =>
implicit val mp: MeterProvider[IO] = otel4s.meterProvider
IORuntimeMetrics
.register[IO](runtime.metrics, IORuntimeMetrics.Config.default)
.surround {
program(otel4s.meterProvider, otel4s.tracerProvider)
}
}
def program(
meterProvider: MeterProvider[IO],
tracerProvider: TracerProvider[IO]
): IO[Unit] = {
val _ = (meterProvider, tracerProvider)
IO.unit
}
}5. OtelJava: seamless context propagation between IO and OpenTelemetry Java SDK
Warning
The IOLocalContextStorageProvider doesn't work with OpenTelemetry Java Agent yet.
Documentation: https://typelevel.org/otel4s/oteljava/tracing-context-propagation.html.
Configure the build.sbt:
libraryDependencies ++= Seq(
"org.typelevel" %% "otel4s-oteljava" % "0.12.0",
"org.typelevel" %% "otel4s-oteljava-context-storage" % "0.12.0",
)
javaOptions += "-Dcats.effect.trackFiberContext=true" Use IOLocalContextStorage.localProvider as a LocalProvider:
import cats.effect.IO
import io.opentelemetry.api.trace.{Span => JSpan}
import org.typelevel.otel4s.context.LocalProvider
import org.typelevel.otel4s.oteljava.IOLocalContextStorage
import org.typelevel.otel4s.oteljava.OtelJava
import org.typelevel.otel4s.oteljava.context.Context
import org.typelevel.otel4s.trace.Tracer
def program(tracer: Tracer[IO]): IO[Unit] =
tracer.span("test").use { span => // start 'test' span using otel4s
println(s"jctx: ${JSpan.current().getSpanContext}") // get a span from a ThreadLocal var
IO.println(s"otel4s: ${span.context}")
}
def run: IO[Unit] = {
implicit val provider: LocalProvider[IO, Context] =
IOLocalContextStorage.localProvider[IO]
OtelJava.autoConfigured[IO]().use { otelJava =>
otelJava.tracerProvider.tracer("com.service").get.flatMap { tracer =>
program(tracer)
}
}
}What's Changed
Core
- core-common: remove public
localForIOLocalinstance by @iRevive in #868 - Add
IORuntimeMetricsby @iRevive in #861 - Add
IOLocalContextStorageby @rossabaker in #214 - Update scalafmt-core to 3.8.5 by @typelevel-steward in #892
- Fix copy/paste errors in docs by @NthPortal in #904
- Add implicit
Otel4s#localContextby @NthPortal in #907 - core-common: redefine
Attributeas a sealed trait by @iRevive in #906 - Add
BaggageManagerutility by @NthPortal in #908 - docs: add
Baggageexample by @iRevive in #915 - core-common: add
Attribute.fromby @iRevive in #911 - docs: update
SpanOps#resourcedocumentation by @iRevive in #924 - core-common: add
Attribute.Makeby @iRevive in #916 - Add implicit
Attribute.Frominstances by @NthPortal in #926
SDK
- sdk: refactor SpanProcessor by @iRevive in #856
- Update cats-effect to
3.6.0-RC1, resolve compilation issues by @iRevive in #866 - Use
MapRef.applyby @iRevive in #880 - Use
SystemPropertiesby @iRevive in #882 - sdk: propagate
Envby @iRevive in #883 - sdk-common: rename
otel.experimental.resource.disabled.keystootel.resource.disabled.keysby @iRevive in #889 - Add
sdk.Context#getOrElseby @NthPortal in #909 - Update opentelemetry-semconv to 1.30.0 by @typelevel-steward in #922
- sdk-trace: remove
exception.escapedattribute by @iRevive in #923
SDK exporter
- sdk-exporter: generate proto models in the private package by @iRevive in #860
- Update fs2 to
3.12.0-RC1, removeepollcatby @iRevive in #884
Semantic Conventions
- Update opentelemetry-semconv to 1.29.0-alpha by @typelevel-steward in #869
OtelJava
- oteljava: refactor Metrics, Traces, and OtelJava API by @iRevive in #867
- oteljava: move
IOLocalContextStorageto thecontextpackage by @iRevive in #879 - Allow instrumentation via OTeL Java Agent by @iRevive in #944
- oteljava-context-storage: update agent instrumentation direction by @iRevive in #948
Documentation
- docs: simplified docker setup with otel-lgtm image by @AlixBa in #871
- Minor documentation tweaks by @iRevive in #877
- docs: add Grafana dashboard link by @iRevive in #878
- Update ecosystem.md: mention otel4s-doobie by @arturaz in #901
Other
- Aggregate
oteljavaproject by @iRevive in #881 - instrumentation-metrics: fix poller metrics by @iRevive in #945
Dependencies
- Update http4s-circe, http4s-dsl, ... to 0.23.30 by @typelevel-steward in #863
- Update opentelemetry-proto to 1.5.0-alpha by @typelevel-steward in #886
- Update pekko-stream to 1.1.3 by @typelevel-steward in #887
- Update scala-library, scala-reflect to 2.13.16 by @typelevel-steward in #891
- Update sbt-typelevel, ... to 0.7.7 by @typelevel-steward in #900
- Update sbt-scalajs, scalajs-compiler, ... to 1.18.2 by @typelevel-steward in #898
- Update scala3-library, ... to 3.3.5 by @typelevel-steward in #905
- Update cats-effect, cats-effect-kernel, ... to 3.6.0-RC2 by @typelevel-...