From 4959cc330c84ac3c6ed16fe56a07b51bfccdf500 Mon Sep 17 00:00:00 2001 From: "Ricardo M. Vilchis" Date: Thu, 19 Oct 2023 14:24:57 -0600 Subject: [PATCH 1/8] fix: updates with generared keys --- .../natchez/extras/doobie/TracedStatement.scala | 3 ++- .../natchez/extras/doobie/TracedTransactor.scala | 14 +++++++++++++- .../extras/doobie/TracedTransactorTest.scala | 3 ++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala index f103ee0..d05b5b8 100644 --- a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala +++ b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala @@ -14,7 +14,8 @@ import scala.annotation.nowarn @nowarn private[doobie] case class TracedStatement( p: PreparedStatement, - queryString: String + queryString: String, + c: Any* ) extends PreparedStatement { def executeQuery(): ResultSet = p.executeQuery() diff --git a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala index 090de4e..2beed19 100644 --- a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala +++ b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala @@ -71,7 +71,7 @@ object TracedTransactor { def runTraced[A](f: TracedOp[A]): TracedOp[A] = Kleisli { - case TracedStatement(p, sql) => + case TracedStatement(p, sql, _*) => Trace[F].span(config.fullyQualifiedSpanName(formatQuery(extractQueryNameOrSql(sql))))( Trace[F].put("span.type" -> "db") >> f(p) ) @@ -93,12 +93,24 @@ object TracedTransactor { override val executeQuery: TracedOp[ResultSet] = runTraced(super.executeQuery) + } override lazy val ConnectionInterpreter: ConnectionInterpreter = new ConnectionInterpreter { override def prepareStatement(a: String): Kleisli[F, Connection, PreparedStatement] = super.prepareStatement(a).map(TracedStatement(_, a): PreparedStatement) + override def prepareStatement( a: String, b: Array[String]): Kleisli[F, Connection, PreparedStatement] = + super.prepareStatement(a, b).map(TracedStatement(_, a, b): PreparedStatement) + override def prepareStatement(a: String, b: Array[Int]): Kleisli[F, Connection, PreparedStatement] = + super.prepareStatement(a, b).map(TracedStatement(_, a, b): PreparedStatement) + override def prepareStatement(a: String, b: Int) = + super.prepareStatement(a, b).map(TracedStatement(_, a, b): PreparedStatement) + override def prepareStatement(a: String, b: Int, c: Int) = + super.prepareStatement(a, b, c).map(TracedStatement(_, a, b, c): PreparedStatement) + override def prepareStatement(a: String, b: Int, c: Int, d: Int) = + super.prepareStatement(a, b, c, d).map(TracedStatement(_, a, b, c, d): PreparedStatement) + override def getTypeMap: Nothing = super.getTypeMap.asInstanceOf // See: https://github.com/tpolecat/doobie/blob/v1.0.0-RC4/modules/core/src/test/scala/doobie/util/StrategySuite.scala#L47 } diff --git a/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala b/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala index 06af640..462ad03 100644 --- a/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala +++ b/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala @@ -65,7 +65,8 @@ class TracedTransactorTest extends CatsEffectSuite { database.test("Trace updates") { db => val create = sql"CREATE TABLE a (id INT, name VARCHAR)".update.run - val insert = sql"INSERT INTO a VALUES (${2: Int}, ${"abc": String})".update.run + val insert = + sql"INSERT INTO a VALUES (${2: Int}, ${"abc": String})".update.withUniqueGeneratedKeys[String]("name") assertIO( run((create >> insert).transact(db)).map(_.last), SpanData("test-db:db.execute:INSERT INTO a VALUES (?, ?)", Map("span.type" -> "db")) From f23c352255cb736aea96695fb89d60d428f754a3 Mon Sep 17 00:00:00 2001 From: Andrii Atamaniv Date: Wed, 22 Nov 2023 15:39:01 +0100 Subject: [PATCH 2/8] AE-2312: libraries upgrade --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 9bea91a..f03cfb8 100644 --- a/build.sbt +++ b/build.sbt @@ -63,13 +63,13 @@ lazy val metricsCommon = projectMatrix .settings(common :+ (name := "natchez-extras-metrics")) val log4catsVersion = "2.6.0" -val natchezVersion = "0.3.3" +val natchezVersion = "0.3.4" val http4sMilestoneVersion = "1.0.0-M40" val http4sStableVersion = "0.23.23" val circeVersion = "0.14.3" val slf4jVersion = "1.7.36" val fs2Version = "3.9.1" -val doobieVersion = "1.0.0-RC4" +val doobieVersion = "1.0.0-RC5" val doobieLegacyVersion = "1.0.0-RC2" lazy val natchezDatadog = projectMatrix From 0c0bbf4c73d88ee700687655d9882de63356a8ce Mon Sep 17 00:00:00 2001 From: Andrii Atamaniv Date: Wed, 22 Nov 2023 19:59:37 +0100 Subject: [PATCH 3/8] AE-2312: libraries upgrade --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index f03cfb8..f2e0576 100644 --- a/build.sbt +++ b/build.sbt @@ -66,7 +66,7 @@ val log4catsVersion = "2.6.0" val natchezVersion = "0.3.4" val http4sMilestoneVersion = "1.0.0-M40" val http4sStableVersion = "0.23.23" -val circeVersion = "0.14.3" +val circeVersion = "0.14.6" val slf4jVersion = "1.7.36" val fs2Version = "3.9.1" val doobieVersion = "1.0.0-RC5" From 8f3b8c44c3326d27296dea79496c7ba7ae3833b9 Mon Sep 17 00:00:00 2001 From: Andrii Atamaniv Date: Wed, 22 Nov 2023 20:49:04 +0100 Subject: [PATCH 4/8] AE-2312: libraries upgrade --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index f2e0576..f03cfb8 100644 --- a/build.sbt +++ b/build.sbt @@ -66,7 +66,7 @@ val log4catsVersion = "2.6.0" val natchezVersion = "0.3.4" val http4sMilestoneVersion = "1.0.0-M40" val http4sStableVersion = "0.23.23" -val circeVersion = "0.14.6" +val circeVersion = "0.14.3" val slf4jVersion = "1.7.36" val fs2Version = "3.9.1" val doobieVersion = "1.0.0-RC5" From 221d7b1c47ffc44eadc002f5bd875abfa1815720 Mon Sep 17 00:00:00 2001 From: Gabor Pihaj Date: Fri, 9 Feb 2024 14:36:10 +0000 Subject: [PATCH 5/8] Re-add existing test so that the fix is tested separately --- .../natchez/extras/doobie/TracedTransactorTest.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala b/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala index 462ad03..f0139b9 100644 --- a/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala +++ b/natchez-extras-doobie/src/test/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactorTest.scala @@ -64,6 +64,16 @@ class TracedTransactorTest extends CatsEffectSuite { } database.test("Trace updates") { db => + val create = sql"CREATE TABLE a (id INT, name VARCHAR)".update.run + val insert = + sql"INSERT INTO a VALUES (${2: Int}, ${"abc": String})".update.run + assertIO( + run((create >> insert).transact(db)).map(_.last), + SpanData("test-db:db.execute:INSERT INTO a VALUES (?, ?)", Map("span.type" -> "db")) + ) + } + + database.test("Trace updates withUniqueGeneratedKeys") { db => val create = sql"CREATE TABLE a (id INT, name VARCHAR)".update.run val insert = sql"INSERT INTO a VALUES (${2: Int}, ${"abc": String})".update.withUniqueGeneratedKeys[String]("name") From 633df8bb780fa77ff6465af24072bab035b9a879 Mon Sep 17 00:00:00 2001 From: Gabor Pihaj Date: Fri, 9 Feb 2024 14:47:51 +0000 Subject: [PATCH 6/8] Remove unused parameters --- .../natchez/extras/doobie/TracedStatement.scala | 3 +-- .../extras/doobie/TracedTransactor.scala | 17 ++++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala index d05b5b8..f103ee0 100644 --- a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala +++ b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedStatement.scala @@ -14,8 +14,7 @@ import scala.annotation.nowarn @nowarn private[doobie] case class TracedStatement( p: PreparedStatement, - queryString: String, - c: Any* + queryString: String ) extends PreparedStatement { def executeQuery(): ResultSet = p.executeQuery() diff --git a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala index 2beed19..c7c4eb3 100644 --- a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala +++ b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala @@ -71,7 +71,7 @@ object TracedTransactor { def runTraced[A](f: TracedOp[A]): TracedOp[A] = Kleisli { - case TracedStatement(p, sql, _*) => + case TracedStatement(p, sql) => Trace[F].span(config.fullyQualifiedSpanName(formatQuery(extractQueryNameOrSql(sql))))( Trace[F].put("span.type" -> "db") >> f(p) ) @@ -100,16 +100,19 @@ object TracedTransactor { new ConnectionInterpreter { override def prepareStatement(a: String): Kleisli[F, Connection, PreparedStatement] = super.prepareStatement(a).map(TracedStatement(_, a): PreparedStatement) - override def prepareStatement( a: String, b: Array[String]): Kleisli[F, Connection, PreparedStatement] = - super.prepareStatement(a, b).map(TracedStatement(_, a, b): PreparedStatement) + override def prepareStatement( + a: String, + b: Array[String] + ): Kleisli[F, Connection, PreparedStatement] = + super.prepareStatement(a, b).map(TracedStatement(_, a): PreparedStatement) override def prepareStatement(a: String, b: Array[Int]): Kleisli[F, Connection, PreparedStatement] = - super.prepareStatement(a, b).map(TracedStatement(_, a, b): PreparedStatement) + super.prepareStatement(a, b).map(TracedStatement(_, a): PreparedStatement) override def prepareStatement(a: String, b: Int) = - super.prepareStatement(a, b).map(TracedStatement(_, a, b): PreparedStatement) + super.prepareStatement(a, b).map(TracedStatement(_, a): PreparedStatement) override def prepareStatement(a: String, b: Int, c: Int) = - super.prepareStatement(a, b, c).map(TracedStatement(_, a, b, c): PreparedStatement) + super.prepareStatement(a, b, c).map(TracedStatement(_, a): PreparedStatement) override def prepareStatement(a: String, b: Int, c: Int, d: Int) = - super.prepareStatement(a, b, c, d).map(TracedStatement(_, a, b, c, d): PreparedStatement) + super.prepareStatement(a, b, c, d).map(TracedStatement(_, a): PreparedStatement) override def getTypeMap: Nothing = super.getTypeMap.asInstanceOf // See: https://github.com/tpolecat/doobie/blob/v1.0.0-RC4/modules/core/src/test/scala/doobie/util/StrategySuite.scala#L47 From f8232a0a84376cbb545518c0ea73e7e602dbdb31 Mon Sep 17 00:00:00 2001 From: Gabor Pihaj Date: Fri, 9 Feb 2024 14:48:44 +0000 Subject: [PATCH 7/8] Remove extra line --- .../com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala index c7c4eb3..274eea5 100644 --- a/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala +++ b/natchez-extras-doobie/src/main/scala/com/ovoenergy/natchez/extras/doobie/TracedTransactor.scala @@ -93,7 +93,6 @@ object TracedTransactor { override val executeQuery: TracedOp[ResultSet] = runTraced(super.executeQuery) - } override lazy val ConnectionInterpreter: ConnectionInterpreter = From 34f6df70ed2543b9dc89eb63fd4725d1a163e923 Mon Sep 17 00:00:00 2001 From: Gabor Pihaj Date: Thu, 11 Apr 2024 09:55:48 +0100 Subject: [PATCH 8/8] Add ability to provide default datadog tags, that will be added to each span --- .../natchez/extras/datadog/Datadog.scala | 7 ++++--- .../natchez/extras/datadog/DatadogTest.scala | 21 ++++++++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/natchez-extras-datadog/src/main/scala/com/ovoenergy/natchez/extras/datadog/Datadog.scala b/natchez-extras-datadog/src/main/scala/com/ovoenergy/natchez/extras/datadog/Datadog.scala index 761d400..e59c947 100644 --- a/natchez-extras-datadog/src/main/scala/com/ovoenergy/natchez/extras/datadog/Datadog.scala +++ b/natchez-extras-datadog/src/main/scala/com/ovoenergy/natchez/extras/datadog/Datadog.scala @@ -9,7 +9,7 @@ import cats.syntax.functor._ import com.ovoenergy.natchez.extras.datadog.DatadogSpan.SpanNames import fs2.Stream import io.circe.{Encoder, Printer} -import natchez.{EntryPoint, Kernel, Span} +import natchez.{EntryPoint, Kernel, Span, TraceValue} import org.http4s.Method.PUT import org.http4s.Uri.Path.unsafeFromString import org.http4s.circe.CirceInstances.builder @@ -119,7 +119,8 @@ object Datadog { client: Client[F], service: String, resource: String, - agentHost: Uri = uri"http://localhost:8126" + agentHost: Uri = uri"http://localhost:8126", + meta: Map[String, TraceValue] = Map.empty ): Resource[F, EntryPoint[F]] = for { queue <- spanQueue @@ -130,7 +131,7 @@ object Datadog { def root(name: String, options: Span.Options): Resource[F, Span[F]] = Resource .eval(SpanIdentifiers.create.flatMap(Ref.of[F, SpanIdentifiers])) - .flatMap(DatadogSpan.create(queue, names(name))) + .flatMap(DatadogSpan.create(queue, names(name), meta)) .widen def continue(name: String, kernel: Kernel, options: Span.Options): Resource[F, Span[F]] = diff --git a/natchez-extras-datadog/src/test/scala/com/ovoenergy/natchez/extras/datadog/DatadogTest.scala b/natchez-extras-datadog/src/test/scala/com/ovoenergy/natchez/extras/datadog/DatadogTest.scala index a70e5d4..a9b7c78 100644 --- a/natchez-extras-datadog/src/test/scala/com/ovoenergy/natchez/extras/datadog/DatadogTest.scala +++ b/natchez-extras-datadog/src/test/scala/com/ovoenergy/natchez/extras/datadog/DatadogTest.scala @@ -7,7 +7,7 @@ import com.ovoenergy.natchez.extras.datadog.Datadog.entryPoint import com.ovoenergy.natchez.extras.datadog.DatadogTags.SpanType.{Cache, Db, Web} import com.ovoenergy.natchez.extras.datadog.DatadogTags.spanType import munit.CatsEffectSuite -import natchez.EntryPoint +import natchez.{EntryPoint, TraceValue} import org.http4s.Request import org.http4s.circe.CirceEntityDecoder._ import org.http4s.syntax.literals._ @@ -21,8 +21,8 @@ import scala.concurrent.duration._ */ class DatadogTest extends CatsEffectSuite { - def run(f: EntryPoint[IO] => IO[Unit]): IO[List[Request[IO]]] = - TestClient[IO].flatMap(c => entryPoint(c.client, "test", "blah").use(f) >> c.requests) + def run(f: EntryPoint[IO] => IO[Unit], meta: Map[String, TraceValue] = Map.empty): IO[List[Request[IO]]] = + TestClient[IO].flatMap(c => entryPoint(c.client, "test", "blah", meta = meta).use(f) >> c.requests) test("Obtain the agent host from the parameter") { assertIO( @@ -126,6 +126,21 @@ class DatadogTest extends CatsEffectSuite { } } + test("Allow you to provide default tags") { + for { + res <- run( + _.root("bar").use(_.span("subspan").use(_ => IO.unit)), + Map("defaultTag1" -> "some-value", "defaultTag2" -> "some-other-value") + ) + spans <- res.flatTraverse(_.as[List[List[SubmittableSpan]]]).map(_.flatten) + } yield { + assertEquals(spans.head.meta.get("defaultTag1"), Some("some-value")) + assertEquals(spans.head.meta.get("defaultTag2"), Some("some-other-value")) + assertEquals(spans.tail.head.meta.get("defaultTag1"), Some("some-value")) + assertEquals(spans.tail.head.meta.get("defaultTag2"), Some("some-other-value")) + } + } + test("Inherit metadata into subspans but only at the time of creation") { run( _.root("bar:res").use { root =>