Skip to content

Releases: typelevel/otel4s

v0.9.0

31 Aug 11:34
5c45dcf
Compare
Choose a tag to compare

We are happy to announce the 0.9.0 release.

Warning

The otel4s-core-metrics, otel4s-core-trace, and otel4s-sdk-trace have several breaking changes and are binary incompatible with the 0.8.x lineage.

Core

1. Macro-based SpanBuilder

Let's take a look at the following example:

Tracer[F]
  .spanBuilder("span")
  .spanKind(SpanKind.Server)
  .addAttributes(Attribute("key", "value"))
  .build
  .use(span => fa(span))

Before 0.9.0, the Attribute("key", "value") would be allocated even if you are using a noop instance (e.g. Tracer.Implicits.noop).

Since 0.9.0, the code above will be rewritten into:

{
  val builder = Tracer[F].spanBuilder("span")
  if (builder.meta.isEnabled) {
    builder.modifyState(_.withSpanKind(SpanKind.Server).addAttributes(Attribute("key", "value")))
  } else {
    builder
  }
}.build.use(span => fa(span))

SDK

These changes are specific to the otel4s-sdk.

1. Span limits

Span limits can be used to control the maximum span size by limiting attributes, events, and links.
The configuration details: https://typelevel.org/otel4s/sdk/configuration.html#span-limits.

Kudos to @bio-aeon.

2. Resource detectors

Resource detectors add environment-specific attributes to the telemetry resource.

The following resource detectors are available out of the box:

  • OS: os.type, os.description
  • Host: host.arch, host.name
  • Process: process.command, process.command_args, process.command_line, process.executable.name, process.executable.path, process.pid, process.owner
  • Runtime: process.runtime.name, process.runtime.version, process.runtime.description

The configuration details: https://typelevel.org/otel4s/sdk/configuration.html#telemetry-resource-detectors.

3. OpenTracing trace propagator

The configuration details: https://typelevel.org/otel4s/sdk/configuration.html#propagators.

Kudos to @o0hgt0o.

What's Changed

  • added OtTracePropagator by @o0hgt0o in #718
  • sdk-common: use CrossType.Full by @iRevive in #720
  • sdk-common: add TelemetryResourceDetector by @iRevive in #721
  • sdk-common: add OSDetector by @iRevive in #723
  • sdk-common: add ProcessRuntimeDetector by @iRevive in #724
  • sdk-trace: define meta: InstrumentMeta[F] as val by @iRevive in #731
  • core-metrics: remove typed backend such as {X}.LongBackend, {X}.DoubleBackend by @iRevive in #733
  • core-metrics: remove Histogram.Meta in favor of InstrumentMeta by @iRevive in #730
  • Trace SDK: introduce span limits support by @bio-aeon in #719
  • core-trace: SpanBuilder use macro to preserve laziness by @iRevive in #734
  • sdk-common: add ProcessDetector by @iRevive in #737
  • oteljava: TextMapPropagatorWrapper - add meaningful toString by @iRevive in #738
  • sdk-common: allow disabling resource detectors from the config by @iRevive in #742

Docs

  • docs: add ecosystem page by @iRevive in #740
  • docs: add cross-service propagation example by @iRevive in #739
  • docs: update OpenTelemetry configuration links by @iRevive in #741
  • docs: add SpanLimits configuration section by @iRevive in #743

Upgrades

  • flake.lock: Update by @typelevel-steward in #736
  • Update fs2-core to 3.11.0 by @typelevel-steward in #735
  • Update opentelemetry-api, ... to 1.41.0 by @typelevel-steward in #722
  • Update opentelemetry-javaagent to 2.7.0 by @typelevel-steward in #727
  • Update opentelemetry-instrumentation-annotations to 2.7.0 by @typelevel-steward in #726
  • Update opentelemetry-semconv to 1.27.0-alpha by @typelevel-steward in #729

New Contributors

Full Changelog: v0.8.1...v0.9.0

v0.8.1

27 Jul 10:09
aea3e7e
Compare
Choose a tag to compare

The release is binary compatible with the 0.8.0.

What's Changed

Improvements and bug fixes

  • sdk-common: config Duration decoder - decode number as milliseconds by @iRevive in #713
  • sdk-exporter: properly construct endpoint URI by @iRevive in #712
  • core-metrics: add varargs apply to the BucketBoundaries by @iRevive in #714

Upgrades

  • flake.lock: Update by @typelevel-steward in #702
  • Update circe-generic to 0.14.8 by @typelevel-steward in #698
  • Update pekko-stream to 1.0.3 by @typelevel-steward in #700
  • Update sbt to 1.10.1 by @typelevel-steward in #705
  • Update sbt-typelevel, ... to 0.7.2 by @typelevel-steward in #707
  • Update opentelemetry-api, ... to 1.40.0 by @typelevel-steward in #704
  • Update opentelemetry-javaagent to 2.6.0 by @typelevel-steward in #709
  • Update opentelemetry-instrumentation-annotations to 2.6.0 by @typelevel-steward in #708
  • Update opentelemetry-semconv to 1.26.0-alpha by @typelevel-steward in #706
  • Update scalafmt-core to 3.8.3 by @typelevel-steward in #715

Full Changelog: v0.8.0...v0.8.1

v0.8.0

03 Jun 07:05
c2d8bff
Compare
Choose a tag to compare

The 0.8.0 release features the synchronous gauge.

Synchronous gauge

A gauge is a synchronous instrument that can record non-additive value(s) (e.g., the background noise level - it makes no sense to record the background noise level value from multiple rooms and sum them up) when changes occur.

The gauge can be used in the following way:

for {
  gauge <- Meter[F].gauge[Long]("long-gauge").create
  _     <- gauge.record(1L, Attribute("key", "value"))
} yield ()

What's Changed

Behind the scene

Upgrades

  • Update opentelemetry-api, ... to 1.38.0 by @typelevel-steward in #678
  • Update opentelemetry-javaagent to 2.4.0 by @typelevel-steward in #681
  • Update opentelemetry-instrumentation-annotations to 2.4.0 by @typelevel-steward in #680
  • Update sbt to 1.10.0 by @typelevel-steward in #672
  • Update sbt-typelevel, ... to 0.7.1 by @typelevel-steward in #673
  • Update munit to 1.0.0 by @typelevel-steward in #683
  • Update munit-cats-effect to 2.0.0 by @typelevel-steward in #684
  • Update cats-core, cats-laws to 2.11.0 by @typelevel-steward in #686
  • Update vault to 3.6.0 by @typelevel-steward in #688
  • flake.lock: Update by @typelevel-steward in #685

Full Changelog: v0.7.0...v0.8.0

v0.7.0

05 May 08:43
9a61034
Compare
Choose a tag to compare

We are happy to announce the 0.7.0 release.

The SDK metrics modules are now publicly available. You can record spans and metrics on any platform: JVM, Scala.js, Scala Native. Check out the documentation.

The otel4s-sdk-metrics module is accompanied by the otel4s-sdk-metrics-testkit module to make testing convenient.
The modules are designed to be nearly a drop-in replacement for otel4s-oteljava.

The implementation remains experimental and some features may be lacking.

Note

The otel4s-core modules are binary compatible with 0.6.0 lineage.

Warning

The otel4s-sdk and otel4s-sdk-exporter have several minor breaking changes and are binary incompatible with the 0.6.0 lineage.

New API

OpenTelemetrySdk#AutoConfigured#addExportersConfigurer

You can use addExportersConfigurer to configure both metrics and traces OTLP exporters:

import cats.effect.IO
import org.typelevel.otel4s.sdk.OpenTelemetrySdk
import org.typelevel.otel4s.sdk.exporter.otlp.autoconfigure.OtlpExportersAutoConfigure
import org.typelevel.otel4s.metrics.MeterProvider
import org.typelevel.otel4s.trace.TracerProvider

OpenTelemetrySdk
  .autoConfigured[IO]( // register OTLP exporters configurer
    _.addExportersConfigurer(OtlpExportersAutoConfigure[IO])
  )
  .use { autoConfigured =>
    val sdk = autoConfigured.sdk
    program(sdk.meterProvider, sdk.tracerProvider)
  }

def program(meterProvider: MeterProvider[IO], tracerProvider: TracerProvider[IO]): IO[Unit] =
  ???

Bugfix

oteljava now captures exemplars correctly

Prior 0.7.0 exemplars weren't linked to the active span correctly.
Starting from 0.7.0 the tracing details of the active span, such as trace_id and span_id, will be added to the captured exemplars.

What's Changed

Improvements and enhancements

Documentation

  • docs: add SDK metrics-specific sections by @iRevive in #659

Internal

oteljava module

  • oteljava: correctly capture exemplars. sdk, oteljava: use shared BaseMeterSuite by @iRevive in #660

sdk-{x} modules

  • sdk-common: add ComponentRegistry by @iRevive in #622
  • sdk-trace: rename LoggingSpanExporter to ConsoleSpanExporter by @iRevive in #651
  • sdk: load MeterProvider in OpenTelemetrySdk by @iRevive in #654
  • sdk: add ExportersAutoConfigure by @iRevive in #658
  • sdk tests: generate more realistic data, omit suchThat by @iRevive in #619

sdk-testkit-{x} modules

  • sdk-testkit: add OpenTelemetrySdkTestkit by @iRevive in #653
  • sdk-metrics-testkit: add MetricsTestkit by @iRevive in #652

sdk-exporter-{x} modules

  • sdk-exporter: add ProtocolAutoConfigure by @iRevive in #656
  • sdk-exporter-metrics: enable module publishing by @iRevive in #666
  • sdk-exporter-metrics: add OtlpHttpMetricExporter by @iRevive in #618
  • sdk-exporter-metrics: add OtlpMetricExporterAutoConfigure by @iRevive in #657
  • sdk-exporter-metrics: add MetricsProtoEncoder by @iRevive in #613
  • sdk-exporter-trace: add OtlpHttpSpanExporter.Builder#withClient by @iRevive in #624

sdk-metrics module

Upgrades

  • Update http4s-circe, http4s-ember-client to 0.23.27 by @typelevel-steward in #662
  • Update scala-library, scala-reflect to 2.13.14 by @typelevel-steward in #661
  • Update sbt-typelevel, ... to 0.7.0 by @typelevel-steward in #617
  • Update circe-generic to 0.14.7 by @typelevel-steward in #648
  • Update munit to 1.0.0-RC1 by @typelevel-steward in #645

Full Changelog: v0.6.0...v0.7.0

v0.6.0

16 Apr 09:08
6358c42
Compare
Choose a tag to compare

We are happy to announce the 0.6.0 release.

Apart from the API improvements and dependency upgrades, there are several new documentation articles:

Note

The otel4s-core and otel4s-oteljava modules are binary compatible with 0.5.0 lineage.

Warning

The otel4s-sdk-exporter has several breaking changes and is binary incompatible with the 0.5.0 lineage.

New API

Span#addLink

You can add a link to another span by using addLink:

val span: Span[F] = ???
val link: SpanContext = ???
span.addLink(link)

OtlpSpanExporterAutoConfigure.customClient

You can supply a preconfigured http4s client to use with the OTLP span exporter. For example, you can provide a JDK11 HTTP client with configured proxy support:

import java.net.{InetSocketAddress, ProxySelector}
import java.net.http.HttpClient
import org.http4s.jdkhttpclient.JdkHttpClient

val jdkHttpClient = HttpClient
  .newBuilder()
  .proxy(ProxySelector.of(InetSocketAddress.createUnresolved("localhost", 3312)))
  .build()
  
OpenTelemetrySdk.autoConfigured[IO](
  _.addSpanExporterConfigurer(
    OtlpSpanExporterAutoConfigure.customClient[IO](JdkHttpClient(jdkHttpClient))
  )
).use { sdk =>
  ???
}

New stable semantic conventions

The semantic conventions have been updated to 1.25.0-alpha. There are several attributes are stable now:

What's Changed

Improvements and enhancements

  • sdk-exporter: allow passing a custom client to the OtlpSpanExporterAutoConfigure by @iRevive in #578
  • trace: add addLink to Span by @iRevive in #587

Documentation

  • Mention the noop tracer for people who just want to use a otel4s enabled library by @benhutchison in #577
  • docs: use otlp/jaeger exporter in the 'Grafana - All-in-one' example by @iRevive in #580
  • docs: add Metrics doc to the instrumentation section by @iRevive in #581
  • docs: add Metrics | JVM Runtime doc to the instrumentation section by @iRevive in #582
  • docs: advice on Honeycomb environments and datasets by @jessitron in #597
  • Docs: separate Scala 2 / Scala 3 examples of the no-op tracer by @iRevive in #590

Internal

  • SemanticConventionsGenerator hook: generate headers by @iRevive in #588

sdk-metrics module (unpublished yet)

Upgrades

  • Update opentelemetry-api, ... to 1.37.0 by @typelevel-steward in #584
  • Update sbt-scalajs, scalajs-compiler, ... to 1.16.0 by @typelevel-steward in #576
  • Update opentelemetry-semconv to 1.25.0-alpha by @typelevel-steward in #585
  • Update opentelemetry-javaagent to 2.3.0 by @typelevel-steward in #593
  • Update opentelemetry-instrumentation-annotations to 2.3.0 by @typelevel-steward in #592
  • Update munit-cats-effect to 2.0.0-M5 by @typelevel-steward in #595

New Contributors

Full Changelog: v0.5.0...v0.6.0

v0.5.0

29 Mar 10:06
21cc202
Compare
Choose a tag to compare

We are happy to announce the 0.5.0 release.
This release brings new features, significant API improvements, and breaking changes.

The SDK tracing modules are now publicly available. Check out the documentation.

Kudos to @NthPortal for numerous API improvements and for making this release happen.

Warning

This version has several breaking changes and is binary incompatible with the 0.4.0 lineage.

Note

Public Scala Steward will rename the artifacts automatically (see the changes below).

Tip

Use the scalafix rule to simplify the migration:

$ sbt "scalafix dependency:V0_5_0Rewrites@org.typelevel:otel4s-scalafix:0.5.0"

Artifacts replacement and package changes

For better clarity, we decided to rename the following artifacts:

  1. otel4s-java to otel4s-oteljava
  2. otel4s-testkit-metrics to otel4s-oteljava-metrics-testkit
- libraryDependencies += "org.typelevel" %% "otel4s-java" % "0.4.0"
+ libraryDependencies += "org.typelevel" %% "otel4s-oteljava" % "0.5.0-RC1"

- libraryDependencies += "org.typelevel" %% "otel4s-testkit-metrics" % "0.4.0"
+ libraryDependencies += "org.typelevel" %% "otel4s-oteljava-metrics-testkit" % "0.5.0-RC1"

The package is renamed, too:

- import org.typelevel.otel4s.java._
+ import org.typelevel.otel4s.oteljava._

The localForIOLocal is moved to a new package

- import org.typelevel.otel4s.java.instances._
+ import org.typelevel.otel4s.instances.local._

Trace Status is renamed to the StatusCode

- import org.typelevel.otel4s.trace.Status
+ import org.typelevel.otel4s.trace.StatusCode

Semantic conventions updated to the 1.24.0

There are several major breaking changes:

  • The experimental (incubating) attributes are moved to a separate module semconv-experimental.
  • Attributes are organized by root namespaces.
    Previously, there were two super-objects ResourceAttributes and SemanticAttributes.
    Now, http.request.header attribute lives in the HttpAttributes object.
  • The package has changed from org.typelevel.otel4s.semconv.trace to org.typelevel.otel4s.semconv.
  • All old attributes that were removed from semantic-conventions (without being deprecated there) have been removed

The stable attributes (for exampleJvmAttributes.scala) are distributed in the otel4s-semconv package:

libraryDependencies += "org.typelevel" %% "otel4s-semconv" % "0.5.0"

However, If you want to use experimental attributes, for example GraphqlExperimentalAttributes.scala, the following dependency is mandatory:

libraryDependencies += "org.typelevel" %% "otel4s-semconv-experimental" % "0.5.0"

Metrics API changes

New generic instrument builders

The instrument builders now require an explicit instrument type:

- val counter = Meter[F].counter("counter").create
+ val counter = Meter[F].counter[Long]("counter").create

- val histogram = Meter[F].histogram("histogram").create
+ val histogram = Meter[F].histogram[Double]("histogram").create

While there is a drawback, this approach allows us to provide a flexible API:

val longCounter: F[Counter[F, Long]] = Meter[F].counter[Long]("counter").create
val doubleCounter: F[Counter[F, Double]] = Meter[F].counter[Double]("counter").create
val longHistogram: F[Histogram[F, Long]] = Meter[F].histogram[Long]("histogram").create
val doubleHistogram: F[Histogram[F, Double]] = Meter[F].histogram[Double]("histogram").create

val doubleGauge: Resource[F, ObservableGauge] =
  Meter[F].observableGauge[Double]("double-gauge").create(Sync[F].delay(List(Measurement(1.0))))

val longGauge: Resource[F, ObservableGauge] =
  Meter[F].observableGauge[Long]("long-gauge").create(Sync[F].delay(List(Measurement(1L))))

As a result, instruments are also available for (almost) any type now.
The underlying type still denotes to either Long or Double. But you can still use a wrapper type:

final case class OpaqueWrapper(value: Long)
implicit val measurementValue: MeasurementValue[OpaqueWrapper] = MeasurementValue[Long].contramap(_.value)

for {
  counter <- Meter[F].counter[OpaqueWrapper]("counter").create
  _       <- counter.add(OpaqueWrapper(42L))
} yield ()

Custom bucket boundaries can be configured via the histogram builder

Meter[F]
  .histogram("service.latency")
  .withExplicitBucketBoundaries(BucketBoundaries(Vector(0.005, 0.05, 0.5, 1.0, 1.5)))
  .create

Tracer API improvements

New Tracer#currentSpanOrThrow API

currentSpanOrThrow throws an exception if no span is available.

val span: F[Span[F]] = Tracer[F].currentSpanOrThrow

SpanOps.Res extractor

It provides access to the span and trace (natural transformation).

tracer.span("resource").resource.use { case SpanOps.Res(span, trace) =>
  ???
}

Array-like attributes use Seq under the hood

Previously, an array-like attribute could be made only with the List collection:

val attribute: Attribute[List[String]] = Attribute("key", List("a", "b"))

We relaxed the type constraint to the Seq:

val seq: Attribute[Seq[String]] = Attribute("key", Seq("a", "b"))
val vectorAsSeq: Attribute[Seq[String]] = Attribute("key", Vector("a", "b"): Seq[String])

Overloaded alternatives to pass attributes

There are overloaded alternatives that take varargs and a collection:

Tracer[F].span("span", Attribute("key", "value")) // varargs
Tracer[F].span("span", List(Attribute("key", "value"))) // collection

Attributes collection

Attributes is a typesafe collection of attributes with handy methods (get, added, concat):

val attributes = Attributes(Attribute("key", "value"), Attribute("frequency", 12.1))
val frequency: Option[Attribute[Double]] = attributes.get[Double]("frequency")
val withAttribute = attributes.added("some.attribute", 123L)

Attributes can be used with Tracer API too:

val attributes = Attributes(Attribute("http.latency", 0.123d), Attribute("user.id", 1L))
Tracer[IO].span("span", attributes)

OtelJava API improvements

New OtelJava.autoConfigured API

A handy option to get an autoconfigured instance which can be customized:

val otelJava: Resource[F, OtelJava[F]] = OtelJava.autoConfigured[F] { builder =>
  builder.addTracerProviderCustomizer((b, _) => b.setSampler(Sampler.alwaysOn()))
}

New OtelJava.noop API

A handy option to get a no-op instance:

val otelJava: F[OtelJava[F]] = OtelJava.noop[F]

New LocalProvider

LocalProvider simplifies the creation of the Local[F, Context]. It automatically detects an available instance or creates a new one. The priorities are the following:

  1. Uses Local[F, Context] available in the scope
  2. Creates Local from IOLocal[Context] and LiftIO[F] available in the scope
  3. Creates new Local[F, Context] by creating IOLocal[Context]

In most cases, you will be unaffected by this change.

OtelJava.localContext provides access to the Local[F, Context]

Now you can access the Local[F, Context] that OtelJava uses for context propagation.
For example, you can inject a baggage:

val otel4s: OtelJava[F] = ???
val program: F[Unit] = ??? 
val baggage = Baggage.builder().put("key", "value").build()

otel4s.localContext.local(program)(ctx => Context.wrap(ctx.underlying.`with`(baggage)))

Simplified conversion between OpenTelemetry Java and otel4s Attributes

import io.opentelemetry.api.common.{Attributes => JAttributes}
import org.typelevel.otel4s.Attributes
import org.typelevel.otel4s.oteljava.AttributeConverters._

val asOtel4s: Attributes =
  JAttributes.builder().put("key", "value").build().toScala
  
val asOpenTelemetry: JAttributes =
  Attributes(Attribute("key", "value")).toJava

OtelJava.underlying provides access to the JOpenTelemetry

Now you can access the JOpenTelemetry that OtelJava uses under the hood:

OtelJava.autoConfigured[IO]() { otel4s =>
  val openTelemetry: io.opentelemetry.api.OpenTelemetry = otel4s.underlying
  ???
}

What's Changed

Improvements and enhancements

Read more

v0.5.0-RC3

24 Mar 10:50
e3fe072
Compare
Choose a tag to compare
v0.5.0-RC3 Pre-release
Pre-release

otel4s-sdk module had a missing dependency in 0.5.0-RC2. 0.5.0-RC3 addresses this issue.

What's Changed

  • site: add SDK section by @iRevive in #533
  • remove sdk-metrics dependency from the sdk by @iRevive in #557
  • Update opentelemetry-javaagent to 2.2.0 by @typelevel-steward in #549
  • Update opentelemetry-instrumentation-annotations to 2.2.0 by @typelevel-steward in #548
  • Update fs2-core to 3.10.0 by @typelevel-steward in #552
  • Update sbt-buildinfo to 0.12.0 by @typelevel-steward in #554

Full Changelog: v0.5.0-RC2...v0.5.0-RC3

v0.5.0-RC2

14 Mar 11:26
558763e
Compare
Choose a tag to compare
v0.5.0-RC2 Pre-release
Pre-release

We are happy to announce the second candidate for the upcoming 0.5.0 release.
The SDK tracing modules are now publicly available. Check out the documentation.

API improvements

There are several improvements. Kudos to @NthPortal for the dedicated work!

1) Attributes collection

Attributes is a typesafe collection of attributes with handy methods (get, added, concat):

val attributes = Attributes(Attribute("key", "value"), Attribute("frequency", 12.1))
val frequency: Option[Attribute[Double]] = attributes.get[Double]("frequency")
val withAttribute = attributes.added("some.attribute", 123L)

Attributes can be used with Tracer API too:

val attributes = Attributes(Attribute("http.latency", 0.123d), Attribute("user.id", 1L))
Tracer[IO].span("span", attributes)

2) Simplified conversion between OpenTelemetry Java and otel4s Attributes

import io.opentelemetry.api.common.{Attributes => JAttributes}
import org.typelevel.otel4s.Attributes
import org.typelevel.otel4s.oteljava.AttributeConverters._

val asOtel4s: Attributes =
  JAttributes.builder().put("key", "value").build().toScala
  
val asOpenTelemetry: JAttributes =
  Attributes(Attribute("key", "value")).toJava

3) OtelJava.underlying provides access to the JOpenTelemetry

Now you can access the JOpenTelemetry that OtelJava uses under the hood:

OtelJava.autoConfigured[IO]() { otel4s =>
  val openTelemetry: io.opentelemetry.api.OpenTelemetry = otel4s.underlying
  ???
}

What's Changed

Improvements and enhancements

Internal

Upgrades

  • Update cats-effect, cats-effect-kernel, ... to 3.5.4 by @typelevel-steward in #538
  • Update http4s-circe, http4s-ember-client to 0.23.26 by @typelevel-steward in #537
  • Update scala3-library, ... to 3.3.3 by @typelevel-steward in #528
  • Update opentelemetry-api, ... to 1.36.0 by @typelevel-steward in #540
  • flake.lock: Update by @typelevel-steward in #546
  • Update scala-library, scala-reflect to 2.13.13 by @typelevel-steward in #523

Full Changelog: v0.5.0-RC1...v0.5.0-RC2

v0.5.0-RC1

27 Feb 19:09
567c711
Compare
Choose a tag to compare
v0.5.0-RC1 Pre-release
Pre-release

We are happy to announce the first candidate for the upcoming 0.5.0 release.
This release brings significant API improvements and breaking changes.

Warning

This version has several breaking changes and is binary incompatible with the 0.4.0 lineage.

Note

Public Scala Steward will rename the artifacts automatically (see the changes below).

Tip

Use the scalafix rule to simplify the migration:

$ sbt "scalafix dependency:V0_5_0Rewrites@org.typelevel:otel4s-scalafix:0.5.0-RC1"

Artifacts replacement and package changes

For better clarity, we decided to rename the following artifacts:

  1. otel4s-java to otel4s-oteljava
  2. otel4s-testkit-metrics to otel4s-oteljava-metrics-testkit
- libraryDependencies += "org.typelevel" %% "otel4s-java" % "0.4.0"
+ libraryDependencies += "org.typelevel" %% "otel4s-oteljava" % "0.5.0-RC1"

- libraryDependencies += "org.typelevel" %% "otel4s-testkit-metrics" % "0.4.0"
+ libraryDependencies += "org.typelevel" %% "otel4s-oteljava-metrics-testkit" % "0.5.0-RC1"

The package is renamed, too:

- import org.typelevel.otel4s.java._
+ import org.typelevel.otel4s.oteljava._

The localForIOLocal is moved to a new package

- import org.typelevel.otel4s.java.instances._
+ import org.typelevel.otel4s.instances.local._

Trace Status is renamed to the StatusCode

- import org.typelevel.otel4s.trace.Status
+ import org.typelevel.otel4s.trace.StatusCode

Notable API changes

Metrics. New generic instrument builders

The instrument builders now require an explicit instrument type:

- val counter = Meter[F].counter("counter").create
+ val counter = Meter[F].counter[Long]("counter").create

- val histogram = Meter[F].histogram("histogram").create
+ val histogram = Meter[F].histogram[Double]("histogram").create

While there is a drawback, this approach allows us to provide a flexible API:

val longCounter: F[Counter[F, Long]] = Meter[F].counter[Long]("counter").create
val doubleCounter: F[Counter[F, Double]] = Meter[F].counter[Double]("counter").create
val longHistogram: F[Histogram[F, Long]] = Meter[F].histogram[Long]("histogram").create
val doubleHistogram: F[Histogram[F, Double]] = Meter[F].histogram[Double]("histogram").create

val doubleGauge: Resource[F, ObservableGauge] =
  Meter[F].observableGauge[Double]("double-gauge").create(Sync[F].delay(List(Measurement(1.0))))

val longGauge: Resource[F, ObservableGauge] =
  Meter[F].observableGauge[Long]("long-gauge").create(Sync[F].delay(List(Measurement(1L))))

As a result, instruments are also available for (almost) any type now.
The underlying type still denotes to either Long or Double. But you can still use a wrapper type:

final case class OpaqueWrapper(value: Long)
implicit val measurementValue: MeasurementValue[OpaqueWrapper] = MeasurementValue[Long].contramap(_.value)

for {
  counter <- Meter[F].counter[OpaqueWrapper]("counter").create
  _       <- counter.add(OpaqueWrapper(42L))
} yield ()

Metrics. Custom bucket boundaries can be configured via the histogram builder

Meter[F]
  .histogram("service.latency")
  .withExplicitBucketBoundaries(BucketBoundaries(Vector(0.005, 0.05, 0.5, 1.0, 1.5)))
  .create

New OtelJava.autoConfigured API

A handy option to get an autoconfigured which can be customized:

val otelJava: Resource[F, OtelJava[F]] = OtelJava.autoConfigured[F] { builder =>
  builder.addTracerProviderCustomizer((b, _) => b.setSampler(Sampler.alwaysOn()))
}

New LocalProvider

LocalProvider simplifies the creation of the Local[F, Context]. It automatically detects an available instance or creates a new one. The priorities are the following:

  1. Uses Local[F, Context] available in the scope
  2. Creates Local from IOLocal[Context] and LiftIO[F] available in the scope
  3. Creates new Local[F, Context] by creating IOLocal[Context]

In most cases, you will be unaffected by this change.

OtelJava.localContext provides access to the Local[F, Context]

Now you can access the Local[F, Context] that OtelJava uses for context propagation.
For example, you can inject a baggage:

val otel4s: OtelJava[F] = ???
val program: F[Unit] = ??? 
val baggage = Baggage.builder().put("key", "value").build()

otel4s.localContext.local(program)(ctx => Context.wrap(ctx.underlying.`with`(baggage)))

Improved Tracer API

There are overloaded alternatives that take varargs and a collection:

Tracer[F].span("span", Attribute("key", "value")) // varargs
Tracer[F].span("span", List(Attribute("key", "value"))) // collection

What's Changed

Improvements and enhancements

sdk module - unpublished yet

Read more

v0.4.0

20 Dec 17:16
db4381d
Compare
Choose a tag to compare

We are happy to announce the 0.4.0 release.

Warning

This version has several breaking changes and is binary incompatible with the 0.3.0 lineage.

Notable API changes

1) Upgraded semantic conventions to 1.23.1

1.23.0 release of the semantic conventions marks HTTP conventions stable.

2) Attributes is a collection now

The Attributes has been redefined as a collection. Now we can take advantages of the built-in methods:

// create using varargs
val attributs: Attributes =
  Attributes(Attribute("key", "value"), Attribute("user_id", 42L))

// or from a collection
val attributs: Attributes =
  Attributes.fromSpecific(Seq(Attribute("key", "value"), Attribute("user_id", 42L)))

// or using a builder
val attributes: Attributes =
  Attributes.newBuilder.addOne("key", "value").addOne("user_id", 42L).result()

// iterable ops: 
attributes.size
attributes.foreach(attribute => println(attribute))
attributes.contains(AttributeKey.string("key"))

// transform to Vector
val asVector: Vector[Attribute[_]] = attributes.to(Vector)

Improvements and clean-ups

Upcoming trace SDK (not published yet)

Behind the scene

  • build.sbt: reorganize munit dependencies by @iRevive in #385
  • IdGeneratorSuite: reduce the number of attempts by @iRevive in #380

Upgrades

  • Update munit-cats-effect to 2.0.0-M4 by @typelevel-steward in #362
  • Update scalafmt-core to 3.7.17 by @typelevel-steward in #376
  • Update sbt-jmh to 0.4.7 by @typelevel-steward in #398
  • Update opentelemetry-api, ... to 1.33.0 by @typelevel-steward in #397
  • Update opentelemetry-instrumentation-annotations to 1.32.0 by @typelevel-steward in #377
  • Update sbt to 1.9.8 by @typelevel-steward in #401
  • Update opentelemetry-javaagent to 1.32.0 by @typelevel-steward in #378
  • Update pekko-stream to 1.0.2 by @typelevel-steward in #392
  • Update sbt-typelevel, ... to 0.6.4 by @typelevel-steward in #402