Skip to content

Commit d528dd0

Browse files
committed
add NoneValue to TraceValue ADT
1 parent 4af5f93 commit d528dd0

File tree

11 files changed

+69
-34
lines changed

11 files changed

+69
-34
lines changed

modules/core/shared/src/main/scala/TraceValue.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ object TraceValue {
1717
case class BooleanValue(value: Boolean) extends TraceValue
1818
case class NumberValue(value: Number) extends TraceValue
1919
case class ListValue(value: List[TraceValue]) extends TraceValue
20+
case object NoneValue extends TraceValue {
21+
override def value: Nothing = throw new IllegalStateException(
22+
"Cannot extract value from NoneValue"
23+
)
24+
}
2025

2126
implicit def viaTraceableValue[A: TraceableValue](a: A): TraceValue =
2227
TraceableValue[A].toTraceValue(a)
@@ -64,4 +69,7 @@ object TraceableValue {
6469

6570
implicit def foldableToTraceValue[F[_]: Foldable, A: TraceableValue]: TraceableValue[F[A]] =
6671
fa => TraceValue.ListValue(fa.toList.map(TraceableValue[A].toTraceValue))
72+
73+
implicit def optionalToTraceValue[A: TraceableValue]: TraceableValue[Option[A]] =
74+
_.fold[TraceValue](TraceValue.NoneValue)(TraceableValue[A].toTraceValue)
6775
}

modules/datadog/src/main/scala/DDSpan.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package natchez
66
package datadog
77

88
import io.{opentracing => ot}
9+
import cats.Applicative
910
import cats.data.Nested
1011
import cats.effect.{Resource, Sync}
1112
import cats.effect.Resource.ExitCase
@@ -43,10 +44,12 @@ final case class DDSpan[F[_]: Sync](
4344

4445
def put(fields: (String, TraceValue)*): F[Unit] =
4546
fields.toList.traverse_ {
46-
case (str, StringValue(value)) => Sync[F].delay(span.setTag(str, value))
47-
case (str, NumberValue(value)) => Sync[F].delay(span.setTag(str, value))
48-
case (str, BooleanValue(value)) => Sync[F].delay(span.setTag(str, value))
49-
case (str, ListValue(v)) => Sync[F].delay(span.setTag(str, v.map(_.toString).mkString(", ")))
47+
case (str, StringValue(value)) => Sync[F].delay(span.setTag(str, value)).void
48+
case (str, NumberValue(value)) => Sync[F].delay(span.setTag(str, value)).void
49+
case (str, BooleanValue(value)) => Sync[F].delay(span.setTag(str, value)).void
50+
case (str, ListValue(v)) =>
51+
Sync[F].delay(span.setTag(str, v.map(_.toString).mkString(", "))).void
52+
case (_, NoneValue) => Applicative[F].unit
5053
}
5154

5255
override def log(fields: (String, TraceValue)*): F[Unit] = {

modules/jaeger/src/main/scala/JaegerSpan.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package natchez
66
package jaeger
77

88
import io.{opentracing => ot}
9+
import cats.Applicative
910
import cats.data.Nested
1011
import cats.effect.Sync
1112
import cats.effect.Resource
@@ -40,10 +41,11 @@ private[jaeger] final case class JaegerSpan[F[_]: Sync](
4041

4142
override def put(fields: (String, TraceValue)*): F[Unit] =
4243
fields.toList.traverse_ {
43-
case (k, StringValue(v)) => Sync[F].delay(span.setTag(k, v))
44-
case (k, NumberValue(v)) => Sync[F].delay(span.setTag(k, v))
45-
case (k, BooleanValue(v)) => Sync[F].delay(span.setTag(k, v))
46-
case (k, ListValue(v)) => Sync[F].delay(span.setTag(k, v.map(_.toString).mkString(", ")))
44+
case (k, StringValue(v)) => Sync[F].delay(span.setTag(k, v)).void
45+
case (k, NumberValue(v)) => Sync[F].delay(span.setTag(k, v)).void
46+
case (k, BooleanValue(v)) => Sync[F].delay(span.setTag(k, v)).void
47+
case (k, ListValue(v)) => Sync[F].delay(span.setTag(k, v.map(_.toString).mkString(", "))).void
48+
case (_, NoneValue) => Applicative[F].unit
4749
}
4850

4951
override def attachError(err: Throwable, fields: (String, TraceValue)*): F[Unit] =

modules/lightstep/src/main/scala/LightstepSpan.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
package natchez
66
package lightstep
77

8+
import cats.Applicative
89
import cats.effect.{Resource, Sync}
9-
import cats.syntax.all._
10+
import cats.syntax.all.*
1011
import io.opentracing.log.Fields
11-
import io.{opentracing => ot}
12+
import io.opentracing as ot
1213
import io.opentracing.propagation.{Format, TextMapAdapter}
1314
import io.opentracing.tag.Tags
1415
import natchez.Span.Options
15-
import natchez.lightstep.Lightstep._
16+
import natchez.lightstep.Lightstep.*
1617

17-
import scala.jdk.CollectionConverters._
18+
import scala.jdk.CollectionConverters.*
1819
import java.net.URI
1920

2021
private[lightstep] final case class LightstepSpan[F[_]: Sync](
@@ -36,10 +37,11 @@ private[lightstep] final case class LightstepSpan[F[_]: Sync](
3637

3738
override def put(fields: (String, TraceValue)*): F[Unit] =
3839
fields.toList.traverse_ {
39-
case (k, StringValue(v)) => Sync[F].delay(span.setTag(k, v))
40-
case (k, NumberValue(v)) => Sync[F].delay(span.setTag(k, v))
41-
case (k, BooleanValue(v)) => Sync[F].delay(span.setTag(k, v))
42-
case (k, ListValue(v)) => Sync[F].delay(span.setTag(k, v.map(_.toString).mkString(", ")))
40+
case (k, StringValue(v)) => Sync[F].delay(span.setTag(k, v)).void
41+
case (k, NumberValue(v)) => Sync[F].delay(span.setTag(k, v)).void
42+
case (k, BooleanValue(v)) => Sync[F].delay(span.setTag(k, v)).void
43+
case (k, ListValue(v)) => Sync[F].delay(span.setTag(k, v.map(_.toString).mkString(", "))).void
44+
case (_, NoneValue) => Applicative[F].unit
4345
}
4446

4547
override def attachError(err: Throwable, fields: (String, TraceValue)*): F[Unit] =

modules/log-odin/src/main/scala/LogSpan.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ private[logodin] object LogSpan {
139139
case NumberValue(n: BigInt) => n.asJson
140140
case NumberValue(n) => n.doubleValue.asJson
141141
case ListValue(vs) => vs.map(EncodeTraceValue(_)).asJson
142+
case NoneValue => Json.Null
142143
}
143144

144145
implicit val KeyEncodeCIString: KeyEncoder[CIString] = KeyEncoder[String].contramap(_.toString)

modules/log/shared/src/main/scala/LogSpan.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ private[log] object LogSpan {
127127
case NumberValue(n: BigInt) => n.asJson
128128
case NumberValue(n) => n.doubleValue.asJson
129129
case ListValue(vs) => vs.map(EncodeTraceValue(_)).asJson
130+
case NoneValue => Json.Null
130131
}
131132

132133
implicit val KeyEncodeCIString: KeyEncoder[CIString] = KeyEncoder[String].contramap(_.toString)

modules/mock/src/main/scala/MockSpan.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package mock
77

88
import scala.jdk.CollectionConverters._
99

10+
import cats.Applicative
1011
import cats.effect.{Resource, Sync}
1112
import cats.syntax.all._
1213
import io.opentracing.log.Fields
@@ -32,10 +33,11 @@ final case class MockSpan[F[_]: Sync](tracer: ot.mock.MockTracer, span: ot.mock.
3233

3334
def put(fields: (String, TraceValue)*): F[Unit] =
3435
fields.toList.traverse_ {
35-
case (k, StringValue(v)) => Sync[F].delay(span.setTag(k, v))
36-
case (k, NumberValue(v)) => Sync[F].delay(span.setTag(k, v))
37-
case (k, BooleanValue(v)) => Sync[F].delay(span.setTag(k, v))
38-
case (k, ListValue(v)) => Sync[F].delay(span.setTag(k, v.map(_.toString).mkString(", ")))
36+
case (k, StringValue(v)) => Sync[F].delay(span.setTag(k, v)).void
37+
case (k, NumberValue(v)) => Sync[F].delay(span.setTag(k, v)).void
38+
case (k, BooleanValue(v)) => Sync[F].delay(span.setTag(k, v)).void
39+
case (k, ListValue(v)) => Sync[F].delay(span.setTag(k, v.map(_.toString).mkString(", "))).void
40+
case (_, NoneValue) => Applicative[F].unit
3941
}
4042

4143
def attachError(err: Throwable, fields: (String, TraceValue)*): F[Unit] =

modules/newrelic/src/main/scala/natchez/newrelic/NewrelicSpan.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package natchez.newrelic
66

7+
import cats.Applicative
78
import java.net.URI
89
import java.util.UUID
910
import cats.effect.Ref
@@ -45,10 +46,11 @@ private[newrelic] final case class NewrelicSpan[F[_]: Sync](
4546

4647
override def put(fields: (String, TraceValue)*): F[Unit] =
4748
fields.toList.traverse_ {
48-
case (k, StringValue(v)) => attributes.update(att => att.put(k, v))
49-
case (k, NumberValue(v)) => attributes.update(att => att.put(k, v))
50-
case (k, BooleanValue(v)) => attributes.update(att => att.put(k, v))
51-
case (k, ListValue(vs)) => attributes.update(att => att.put(k, vs.mkString(", ")))
49+
case (k, StringValue(v)) => attributes.update(att => att.put(k, v)).void
50+
case (k, NumberValue(v)) => attributes.update(att => att.put(k, v)).void
51+
case (k, BooleanValue(v)) => attributes.update(att => att.put(k, v)).void
52+
case (k, ListValue(vs)) => attributes.update(att => att.put(k, vs.mkString(", "))).void
53+
case (_, NoneValue) => Applicative[F].unit
5254
}
5355

5456
override def attachError(err: Throwable, fields: (String, TraceValue)*): F[Unit] =

modules/opencensus/src/main/scala/OpenCensusSpan.scala

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,38 @@ private[opencensus] final case class OpenCensusSpan[F[_]: Sync](
3232
override protected val spanCreationPolicyOverride: Options.SpanCreationPolicy =
3333
options.spanCreationPolicy
3434

35-
private def traceToAttribute(value: TraceValue): AttributeValue = value match {
35+
private def traceToAttribute(value: TraceValue): Option[AttributeValue] = value match {
3636
case StringValue(v) =>
3737
val safeString = if (v == null) "null" else v
38-
AttributeValue.stringAttributeValue(safeString)
38+
AttributeValue.stringAttributeValue(safeString).some
3939
case NumberValue(v) =>
40-
AttributeValue.doubleAttributeValue(v.doubleValue())
40+
AttributeValue.doubleAttributeValue(v.doubleValue()).some
4141
case BooleanValue(v) =>
42-
AttributeValue.booleanAttributeValue(v)
42+
AttributeValue.booleanAttributeValue(v).some
4343
case ListValue(v) =>
44-
AttributeValue.stringAttributeValue(v.map(_.toString).mkString(", "))
44+
AttributeValue.stringAttributeValue(v.map(_.toString).mkString(", ")).some
45+
case NoneValue => None
4546
}
4647

48+
private def fieldsToAttributeValues(
49+
fields: List[(String, TraceValue)]
50+
): List[(String, AttributeValue)] =
51+
fields.nested
52+
.map(traceToAttribute)
53+
.value
54+
.collect { case (key, Some(value)) =>
55+
key -> value
56+
}
57+
4758
override def put(fields: (String, TraceValue)*): F[Unit] =
48-
fields.toList.traverse_ { case (key, value) =>
49-
Sync[F].delay(span.putAttribute(key, traceToAttribute(value)))
50-
}
59+
fieldsToAttributeValues(fields.toList)
60+
.traverse_ { case (key, value) =>
61+
Sync[F].delay(span.putAttribute(key, value))
62+
}
5163

5264
override def log(fields: (String, TraceValue)*): F[Unit] = {
53-
val map = fields.map { case (k, v) => k -> traceToAttribute(v) }.toMap.asJava
54-
Sync[F].delay(span.addAnnotation("event", map)).void
65+
val map = fieldsToAttributeValues(fields.toList).toMap.asJava
66+
Sync[F].delay(span.addAnnotation("event", map)).unlessA(map.isEmpty)
5567
}
5668

5769
override def log(event: String): F[Unit] =

modules/opentelemetry/src/main/scala/natchez/opentelemetry/OpenTelemetrySpan.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ private[opentelemetry] final case class OpenTelemetrySpan[F[_]: Sync](
7676
case ListValue(v) => v.mkString(", ")
7777
}
7878
bldr.put(k, strings: _*)
79+
case (_, NoneValue) => ()
7980
}
8081
bldr.build()
8182
}

0 commit comments

Comments
 (0)