diff --git a/core/trace/src/main/scala/org/typelevel/otel4s/trace/Span.scala b/core/trace/src/main/scala/org/typelevel/otel4s/trace/Span.scala index 2a1258526..64f9a1b90 100644 --- a/core/trace/src/main/scala/org/typelevel/otel4s/trace/Span.scala +++ b/core/trace/src/main/scala/org/typelevel/otel4s/trace/Span.scala @@ -71,6 +71,20 @@ trait Span[F[_]] extends SpanMacro[F] { final def context: SpanContext = backend.context + /** Updates the name of the [[Span]]. + * + * '''Note''': if used, this will override the name provided via the + * [[SpanBuilder]]. + * + * '''Caution''': upon this update, any sampling behavior based on span's + * name will depend on the implementation. + * + * @param name + * the new name of the span + */ + final def updateName(name: String): F[Unit] = + backend.updateName(name) + /** Marks the end of [[Span]] execution. * * Only the timing of the first end call for a given span will be recorded, @@ -102,6 +116,8 @@ object Span { def meta: InstrumentMeta[F] def context: SpanContext + def updateName(name: String): F[Unit] + def addAttributes(attributes: Attribute[_]*): F[Unit] def addEvent(name: String, attributes: Attribute[_]*): F[Unit] @@ -131,6 +147,8 @@ object Span { val meta: InstrumentMeta[F] = InstrumentMeta.disabled val context: SpanContext = SpanContext.invalid + def updateName(name: String): F[Unit] = unit + def addAttributes(attributes: Attribute[_]*): F[Unit] = unit def addEvent(name: String, attributes: Attribute[_]*): F[Unit] = unit diff --git a/java/trace/src/main/scala/org/typelevel/otel4s/java/trace/SpanBackendImpl.scala b/java/trace/src/main/scala/org/typelevel/otel4s/java/trace/SpanBackendImpl.scala index c4dc3b80e..2c9f63446 100644 --- a/java/trace/src/main/scala/org/typelevel/otel4s/java/trace/SpanBackendImpl.scala +++ b/java/trace/src/main/scala/org/typelevel/otel4s/java/trace/SpanBackendImpl.scala @@ -40,6 +40,12 @@ private[java] class SpanBackendImpl[F[_]: Sync]( def context: SpanContext = spanContext + def updateName(name: String): F[Unit] = + Sync[F].delay { + jSpan.updateName(name) + () + } + def addAttributes(attributes: Attribute[_]*): F[Unit] = Sync[F].delay { jSpan.setAllAttributes(Conversions.toJAttributes(attributes)) diff --git a/java/trace/src/test/scala/org/typelevel/otel4s/java/trace/TracerSuite.scala b/java/trace/src/test/scala/org/typelevel/otel4s/java/trace/TracerSuite.scala index e981a96ab..a80a6f7d8 100644 --- a/java/trace/src/test/scala/org/typelevel/otel4s/java/trace/TracerSuite.scala +++ b/java/trace/src/test/scala/org/typelevel/otel4s/java/trace/TracerSuite.scala @@ -86,6 +86,15 @@ class TracerSuite extends CatsEffectSuite { ) } + test("update span name") { + for { + sdk <- makeSdk() + tracer <- sdk.provider.get("tracer") + _ <- tracer.span("span").use(span => span.updateName("span-use")) + spans <- sdk.finishedSpans + } yield assertEquals(spans.map(_.getName), List("span-use")) + } + test("set attributes only once") { val key = "string-attribute" val value = "value"