diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 921ceff7b..042e40690 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: ci: - runs-on: self-hosted + runs-on: ubuntu-latest env: JAVA_OPTS: -Xms5120M -Xmx5120M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 JVM_OPTS: -Xms5120M -Xmx5120M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0275e2148..366f676e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,7 +6,7 @@ on: jobs: release: - runs-on: self-hosted + runs-on: ubuntu-latest env: JAVA_OPTS: -Xms5120M -Xmx5120M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 JVM_OPTS: -Xms5120M -Xmx5120M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 diff --git a/build.sbt b/build.sbt index e1d5a0687..0243958c7 100644 --- a/build.sbt +++ b/build.sbt @@ -36,7 +36,6 @@ lazy val `kamon-core` = (project in file("core/kamon-core")) .settings( buildInfoKeys := Seq[BuildInfoKey](version), buildInfoPackage := "kamon.status", - crossScalaVersions += `scala_3_version`, scalacOptions ++= { if(scalaBinaryVersion.value == "2.11") Seq("-Ydelambdafy:method") else Seq.empty }, assembly / assemblyShadeRules := Seq( ShadeRule.rename("org.jctools.**" -> "kamon.lib.@0").inAll, @@ -71,7 +70,6 @@ lazy val `kamon-core` = (project in file("core/kamon-core")) lazy val `kamon-status-page` = (project in file("core/kamon-status-page")) .enablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, assembly / assemblyShadeRules := Seq( ShadeRule.rename("com.grack.nanojson.**" -> "kamon.lib.@0").inAll, ShadeRule.rename("fi.iki.elonen.**" -> "kamon.lib.@0").inAll, @@ -86,7 +84,6 @@ lazy val `kamon-status-page` = (project in file("core/kamon-status-page")) lazy val `kamon-testkit` = (project in file("core/kamon-testkit")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies += scalatest % "provided,test" ).dependsOn(`kamon-core`) @@ -95,7 +92,6 @@ lazy val `kamon-core-tests` = (project in file("core/kamon-core-tests")) .disablePlugins(AssemblyPlugin) .settings(noPublishing: _*) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( scalatest % "test", logbackClassic % "test" @@ -106,7 +102,6 @@ lazy val `kamon-core-tests` = (project in file("core/kamon-core-tests")) lazy val `kamon-core-bench` = (project in file("core/kamon-core-bench")) .disablePlugins(AssemblyPlugin) .enablePlugins(JmhPlugin) - .settings(crossScalaVersions += `scala_3_version`) .settings(noPublishing: _*) .dependsOn(`kamon-core`) @@ -162,9 +157,6 @@ lazy val `kamon-instrumentation-common` = (project in file("instrumentation/kamo .disablePlugins(AssemblyPlugin) .enablePlugins(JavaAgent) .settings(instrumentationSettings) - .settings( - crossScalaVersions += `scala_3_version`, - ) .settings( resolvers += Resolver.mavenLocal, libraryDependencies ++= Seq( @@ -178,7 +170,6 @@ lazy val `kamon-instrumentation-common` = (project in file("instrumentation/kamo lazy val `kamon-executors` = (project in file("instrumentation/kamon-executors")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( kanelaAgent % "provided", scalatest % "test", @@ -204,6 +195,7 @@ lazy val `kamon-twitter-future` = (project in file("instrumentation/kamon-twitte .enablePlugins(JavaAgent) .settings(instrumentationSettings) .settings( + crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`), libraryDependencies ++= Seq( kanelaAgent % "provided", "com.twitter" %% "util-core" % "20.3.0" % "provided", @@ -218,6 +210,7 @@ lazy val `kamon-scalaz-future` = (project in file("instrumentation/kamon-scalaz- .enablePlugins(JavaAgent) .settings(instrumentationSettings) .settings( + crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`), libraryDependencies ++= Seq( kanelaAgent % "provided", "org.scalaz" %% "scalaz-concurrent" % "7.2.28" % "provided", @@ -231,7 +224,6 @@ lazy val `kamon-scala-future` = (project in file("instrumentation/kamon-scala-fu .disablePlugins(AssemblyPlugin) .enablePlugins(JavaAgent) .settings(instrumentationSettings) - .settings(crossScalaVersions += `scala_3_version`) .settings( libraryDependencies ++=Seq( kanelaAgent % "provided", @@ -246,6 +238,7 @@ lazy val `kamon-cats-io` = (project in file("instrumentation/kamon-cats-io")) .enablePlugins(JavaAgent) .settings(instrumentationSettings) .settings( + crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`), libraryDependencies ++= Seq( kanelaAgent % "provided", { @@ -289,6 +282,10 @@ lazy val `kamon-logback` = (project in file("instrumentation/kamon-logback")) ).dependsOn(`kamon-core`, `kamon-instrumentation-common`, `kamon-testkit` % "test") +def slickVersion(scalaVersion: String) = scalaVersion match { + case "3" => "3.5.0-M5" + case x => "3.3.2" +} lazy val `kamon-jdbc` = (project in file("instrumentation/kamon-jdbc")) .disablePlugins(AssemblyPlugin) .enablePlugins(JavaAgent) @@ -299,15 +296,15 @@ lazy val `kamon-jdbc` = (project in file("instrumentation/kamon-jdbc")) kanelaAgent % "provided", "com.zaxxer" % "HikariCP" % "4.0.3" % "provided", "org.mariadb.jdbc" % "mariadb-java-client" % "2.2.6" % "provided", - "com.typesafe.slick" %% "slick" % "3.3.2" % "provided", + "com.typesafe.slick" %% "slick" % slickVersion(scalaBinaryVersion.value) % "provided", "org.postgresql" % "postgresql" % "42.2.5" % "provided", scalatest % "test", logbackClassic % "test", - "com.typesafe.slick" %% "slick-hikaricp" % "3.3.2" % "test", - "com.h2database" % "h2" % "1.4.182" % "test", + "com.typesafe.slick" %% "slick-hikaricp" % slickVersion(scalaBinaryVersion.value) % "test", + "com.h2database" % "h2" % "1.4.192" % "test", "org.xerial" % "sqlite-jdbc" % "3.34.0" % "test", - "ch.vorburger.mariaDB4j" % "mariaDB4j" % "2.4.0" % "test" + "ch.vorburger.mariaDB4j" % "mariaDB4j" % "2.5.3" % "test" ) ).dependsOn(`kamon-core`, `kamon-executors`, `kamon-testkit` % "test") @@ -316,7 +313,6 @@ lazy val `kamon-kafka` = (project in file("instrumentation/kamon-kafka")) .disablePlugins(AssemblyPlugin) .enablePlugins(JavaAgent) .settings(instrumentationSettings) - .settings(crossScalaVersions += `scala_3_version`) .settings( libraryDependencies ++= Seq( kanelaAgent % "provided", @@ -334,6 +330,7 @@ lazy val `kamon-mongo-legacy` = (project in file("instrumentation/kamon-mongo-le .enablePlugins(JavaAgent) .settings(instrumentationSettings) .settings( + crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`), libraryDependencies ++= Seq( kanelaAgent % "provided", "org.mongodb" % "mongodb-driver-sync" % "3.11.0" % "provided", @@ -352,6 +349,7 @@ lazy val `kamon-mongo` = (project in file("instrumentation/kamon-mongo")) .enablePlugins(JavaAgent) .settings(instrumentationSettings) .settings( + crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`), libraryDependencies ++= Seq( kanelaAgent % "provided", "org.mongodb" % "mongodb-driver-sync" % "4.2.3" % "provided", @@ -368,6 +366,7 @@ lazy val `kamon-cassandra` = (project in file("instrumentation/kamon-cassandra") .disablePlugins(AssemblyPlugin) .enablePlugins(JavaAgent) .settings(instrumentationSettings) + .settings(crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`)) .dependsOn(`kamon-core`, `kamon-instrumentation-common`, `kamon-testkit` % "test", `kamon-executors`) lazy val `kamon-elasticsearch` = (project in file("instrumentation/kamon-elasticsearch")) @@ -382,8 +381,8 @@ lazy val `kamon-elasticsearch` = (project in file("instrumentation/kamon-elastic "org.elasticsearch.client" % "elasticsearch-rest-high-level-client" % "7.9.1" % "provided", scalatest % "test", logbackClassic % "test", - "com.dimafeng" %% "testcontainers-scala" % "0.39.3" % "test", - "com.dimafeng" %% "testcontainers-scala-elasticsearch" % "0.39.3" % "test" + "com.dimafeng" %% "testcontainers-scala" % "0.41.0" % "test", + "com.dimafeng" %% "testcontainers-scala-elasticsearch" % "0.41.0" % "test" ) ).dependsOn(`kamon-core`, `kamon-instrumentation-common`, `kamon-testkit` % "test") @@ -422,7 +421,6 @@ lazy val `kamon-annotation` = (project in file("instrumentation/kamon-annotation .enablePlugins(AssemblyPlugin) .settings(instrumentationSettings: _*) .settings( - crossScalaVersions += `scala_3_version`, assembly / assemblyShadeRules := Seq( ShadeRule.rename("javax.el.**" -> "kamon.lib.@0").inAll, ShadeRule.rename("com.sun.el.**" -> "kamon.lib.@0").inAll, @@ -443,7 +441,6 @@ lazy val `kamon-annotation` = (project in file("instrumentation/kamon-annotation lazy val `kamon-system-metrics` = (project in file("instrumentation/kamon-system-metrics")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( oshiCore, scalatest % "test", @@ -456,7 +453,6 @@ lazy val `kamon-akka` = (project in file("instrumentation/kamon-akka")) .enablePlugins(JavaAgent) .disablePlugins(AssemblyPlugin) .settings(instrumentationSettings: _*) - .settings(crossScalaVersions += `scala_3_version`) .dependsOn( `kamon-scala-future` % "compile,common,akka-2.5,akka-2.6", `kamon-testkit` % "test,test-common,test-akka-2.5,test-akka-2.6" @@ -506,7 +502,6 @@ lazy val `kamon-akka-http` = (project in file("instrumentation/kamon-akka-http") "de.heikoseeberger" %% "akka-http-json4s" % "1.27.0" % "test" cross CrossVersion.for3Use2_13 intransitive(), "org.json4s" %% "json4s-native" % "4.0.6" % "test", ))) - .settings(crossScalaVersions += `scala_3_version`) .dependsOn(`kamon-akka`, `kamon-testkit` % "test") @@ -603,7 +598,8 @@ lazy val `kamon-akka-grpc` = (project in file("instrumentation/kamon-akka-grpc") lazy val `kamon-play` = (project in file("instrumentation/kamon-play")) .enablePlugins(JavaAgent) .disablePlugins(AssemblyPlugin) - .settings(instrumentationSettings) + .settings(instrumentationSettings, + crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`)) .dependsOn( `kamon-akka` % "compile,test-common,test-play-2.8,test-play-2.7,test-play-2.6", `kamon-akka-http` % "compile,test-common,test-play-2.8,test-play-2.7,test-play-2.6", @@ -657,7 +653,6 @@ lazy val `kamon-redis` = (project in file("instrumentation/kamon-redis")) .enablePlugins(JavaAgent) .settings(instrumentationSettings) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( kanelaAgent % "provided", "redis.clients" % "jedis" % "3.6.0" % "provided", @@ -675,7 +670,6 @@ lazy val `kamon-caffeine` = (project in file("instrumentation/kamon-caffeine")) .enablePlugins(JavaAgent) .settings(instrumentationSettings) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( kanelaAgent % "provided", "com.github.ben-manes.caffeine" % "caffeine" % "2.8.5" % "provided", @@ -689,6 +683,7 @@ lazy val `kamon-caffeine` = (project in file("instrumentation/kamon-caffeine")) lazy val `kamon-lagom` = (project in file("instrumentation/kamon-lagom")) .disablePlugins(AssemblyPlugin) .settings( + crossScalaVersions := Seq(`scala_2.11_version`, `scala_2.12_version`, `scala_2.13_version`), libraryDependencies ++= { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, scalaMajor)) if scalaMajor == 11 => providedScope("com.lightbend.lagom" %% "lagom-server" % "1.4.13") @@ -772,7 +767,6 @@ lazy val reporters = (project in file("reporters")) lazy val `kamon-datadog` = (project in file("reporters/kamon-datadog")) .enablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, assembly / assemblyMergeStrategy := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case _ => MergeStrategy.first @@ -797,7 +791,6 @@ lazy val `kamon-datadog` = (project in file("reporters/kamon-datadog")) lazy val `kamon-apm-reporter` = (project in file("reporters/kamon-apm-reporter")) .enablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, assembly / test := {}, assembly / assemblyMergeStrategy := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard @@ -830,7 +823,6 @@ lazy val `kamon-apm-reporter` = (project in file("reporters/kamon-apm-reporter") lazy val `kamon-statsd` = (project in file("reporters/kamon-statsd")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies += scalatest % Test, ).dependsOn(`kamon-core`) @@ -838,7 +830,6 @@ lazy val `kamon-statsd` = (project in file("reporters/kamon-statsd")) lazy val `kamon-zipkin` = (project in file("reporters/kamon-zipkin")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( "io.zipkin.reporter2" % "zipkin-reporter" % "2.7.15", "io.zipkin.reporter2" % "zipkin-sender-okhttp3" % "2.7.15", @@ -850,7 +841,6 @@ lazy val `kamon-zipkin` = (project in file("reporters/kamon-zipkin")) lazy val `kamon-jaeger` = (project in file("reporters/kamon-jaeger")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( "io.jaegertracing" % "jaeger-thrift" % "1.8.1", scalatest % "test" @@ -861,7 +851,6 @@ lazy val `kamon-jaeger` = (project in file("reporters/kamon-jaeger")) lazy val `kamon-influxdb` = (project in file("reporters/kamon-influxdb")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( okHttp, okHttpMockServer % "test", @@ -873,7 +862,6 @@ lazy val `kamon-influxdb` = (project in file("reporters/kamon-influxdb")) lazy val `kamon-graphite` = (project in file("reporters/kamon-graphite")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( scalatest % "test", logbackClassic % "test" @@ -884,7 +872,6 @@ lazy val `kamon-graphite` = (project in file("reporters/kamon-graphite")) lazy val `kamon-newrelic` = (project in file("reporters/kamon-newrelic")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( "com.newrelic.telemetry" % "telemetry-core" % "0.15.0", "com.newrelic.telemetry" % "telemetry-http-okhttp" % "0.15.0", @@ -896,7 +883,6 @@ lazy val `kamon-newrelic` = (project in file("reporters/kamon-newrelic")) lazy val `kamon-opentelemetry` = (project in file("reporters/kamon-opentelemetry")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( "io.opentelemetry" % "opentelemetry-exporter-otlp-http-trace" % "1.13.0", "io.opentelemetry" % "opentelemetry-exporter-otlp-trace" % "1.13.0", @@ -911,7 +897,6 @@ lazy val `kamon-opentelemetry` = (project in file("reporters/kamon-opentelemetry lazy val `kamon-prometheus` = (project in file("reporters/kamon-prometheus")) .disablePlugins(AssemblyPlugin) .settings( - crossScalaVersions += `scala_3_version`, libraryDependencies ++= Seq( okHttp, scalatest % "test", @@ -930,6 +915,7 @@ lazy val bundle = (project in file("bundle")) .aggregate( `kamon-bundle`, `kamon-bundle_2_11`, + `kamon-bundle-3`, `kamon-runtime-attacher` ) @@ -1050,6 +1036,41 @@ lazy val `kamon-bundle-dependencies-2-12-and-up` = (project in file("bundle/kamo `kamon-alpakka-kafka` ) +/** + * Add a reference here to all the project dependencies that can be built + * for 3 + */ +lazy val `kamon-bundle-dependencies-3` = (project in file("bundle/kamon-bundle-dependencies-3")) + .disablePlugins(AssemblyPlugin) + .settings(noPublishing: _*) + .settings(ideSkipProject: _*) + .dependsOn( + `kamon-runtime-attacher`, + `kamon-status-page`, + `kamon-instrumentation-common`, + `kamon-executors`, + `kamon-scala-future`, + `kamon-logback`, + `kamon-jdbc`, + `kamon-kafka`, + `kamon-elasticsearch`, + `kamon-spring`, + `kamon-annotation`, + `kamon-annotation-api`, + `kamon-system-metrics`, + `kamon-akka`, + `kamon-akka-http`, + `kamon-akka-grpc`, + `kamon-redis`, + `kamon-okhttp`, + `kamon-caffeine`, + `kamon-aws-sdk`, + `kamon-cats-io-3`, + `kamon-pekko`, + `kamon-pekko-http`, + `kamon-pekko-grpc` + ) + lazy val `kamon-bundle` = (project in file("bundle/kamon-bundle")) .enablePlugins(AssemblyPlugin) .settings(commonBundleSettings) @@ -1065,6 +1086,19 @@ lazy val `kamon-bundle` = (project in file("bundle/kamon-bundle")) `kamon-bundle-dependencies-2-12-and-up` % "shaded" ) +lazy val `kamon-bundle-3` = (project in file("bundle/kamon-bundle-3")) + .enablePlugins(AssemblyPlugin) + .settings(commonBundleSettings) + .settings(ideSkipProject: _*) + .settings( + scalaVersion := scala_3_version, + crossScalaVersions := Seq(scala_3_version) + ) + .dependsOn( + `kamon-core`, + `kamon-bundle-dependencies-3` % "shaded" + ) + lazy val `kamon-bundle_2_11` = (project in file("bundle/kamon-bundle_2.11")) .enablePlugins(AssemblyPlugin) .settings(commonBundleSettings) diff --git a/instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/ActorInstrumentation.scala b/instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/ActorInstrumentationCommon.scala similarity index 100% rename from instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/ActorInstrumentation.scala rename to instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/ActorInstrumentationCommon.scala diff --git a/instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/EventStreamInstrumentation.scala b/instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/EventStreamInstrumentationCommon.scala similarity index 100% rename from instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/EventStreamInstrumentation.scala rename to instrumentation/kamon-akka/src/common/scala/kamon/instrumentation/akka/instrumentations/EventStreamInstrumentationCommon.scala diff --git a/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ConnectionPoolAdvices.scala b/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ConnectionPoolAdvices.scala index e114f590c..edd2c82cb 100644 --- a/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ConnectionPoolAdvices.scala +++ b/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ConnectionPoolAdvices.scala @@ -24,10 +24,13 @@ import kamon.instrumentation.cassandra.CassandraInstrumentation import kamon.util.CallingThreadExecutionContext import kanela.agent.libs.net.bytebuddy.asm.Advice +import scala.annotation.static + +class PoolConstructorAdvice object PoolConstructorAdvice { @Advice.OnMethodExit - def onConstructed( + @static def onConstructed( @Advice.This poolWithMetrics: HostConnectionPool with HasPoolMetrics, @Advice.FieldValue("host") host: Host, @Advice.FieldValue("totalInFlight") totalInflight: AtomicInteger @@ -46,10 +49,11 @@ object PoolConstructorAdvice { } } +class PoolCloseAdvice object PoolCloseAdvice { @Advice.OnMethodExit - def onClose(@Advice.This poolWithMetrics: HostConnectionPool with HasPoolMetrics): Unit = { + @static def onClose(@Advice.This poolWithMetrics: HostConnectionPool with HasPoolMetrics): Unit = { poolWithMetrics.nodeMonitor.cleanup() } } @@ -62,12 +66,12 @@ class BorrowAdvice object BorrowAdvice { @Advice.OnMethodEnter - def startBorrow(@Advice.This poolMetrics: HasPoolMetrics): Long = { + @static def startBorrow(@Advice.This poolMetrics: HasPoolMetrics): Long = { Kamon.clock().nanos() } @Advice.OnMethodExit(suppress = classOf[Throwable], inline = false) - def onBorrowed( + @static def onBorrowed( @Advice.Return connection: ListenableFuture[Connection], @Advice.Enter start: Long, @Advice.This poolMetrics: HasPoolMetrics, @@ -91,10 +95,11 @@ object BorrowAdvice { * Incremented when new connection requested and decremented either on * connection being explicitly trashed or defunct */ +class InitPoolAdvice object InitPoolAdvice { @Advice.OnMethodExit - def onPoolInited( + @static def onPoolInited( @Advice.This hasPoolMetrics: HasPoolMetrics, @Advice.Return done: ListenableFuture[_], @Advice.FieldValue("open") openConnections: AtomicInteger @@ -108,10 +113,11 @@ object InitPoolAdvice { } } +class CreateConnectionAdvice object CreateConnectionAdvice { @Advice.OnMethodExit - def onConnectionCreated( + @static def onConnectionCreated( @Advice.This hasPoolMetrics: HasPoolMetrics, @Advice.Return created: Boolean ): Unit = @@ -120,10 +126,11 @@ object CreateConnectionAdvice { } } +class TrashConnectionAdvice object TrashConnectionAdvice { @Advice.OnMethodExit - def onConnectionTrashed( + @static def onConnectionTrashed( @Advice.This hasPoolMetrics: HasPoolMetrics, @Advice.FieldValue("host") host: Host ): Unit = { @@ -131,10 +138,11 @@ object TrashConnectionAdvice { } } +class ConnectionDefunctAdvice object ConnectionDefunctAdvice { @Advice.OnMethodExit - def onConnectionDefunct(@Advice.This hasPoolMetrics: HasPoolMetrics): Unit = { + @static def onConnectionDefunct(@Advice.This hasPoolMetrics: HasPoolMetrics): Unit = { hasPoolMetrics.nodeMonitor.connectionClosed } } diff --git a/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ExecutionAdvices.scala b/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ExecutionAdvices.scala index 97aaef0b4..77fe4b5e1 100644 --- a/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ExecutionAdvices.scala +++ b/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/ExecutionAdvices.scala @@ -17,7 +17,6 @@ package com.datastax.driver.core import java.util.concurrent.atomic.AtomicReference - import com.datastax.driver.core.Message.Response import com.datastax.driver.core.RequestHandler.QueryState import kamon.Kamon @@ -31,6 +30,8 @@ import kamon.instrumentation.context.HasContext import kamon.trace.Span import kanela.agent.libs.net.bytebuddy.asm.Advice +import scala.annotation.static + object QueryOperations { val QueryOperationName = "cassandra.query" val BatchOperationName = "cassandra.batch" @@ -38,13 +39,14 @@ object QueryOperations { val ExecutionOperationName: String = QueryOperationName + ".execution" } +class QueryExecutionAdvice object QueryExecutionAdvice { import QueryOperations._ val ParentSpanKey: Context.Key[Span] = Context.key[Span]("__parent-span", Span.Empty) @Advice.OnMethodEnter - def onQueryExec( + @static def onQueryExec( @Advice.This execution: HasContext, @Advice.Argument(0) host: Host with HasPoolMetrics, @Advice.FieldValue("position") position: Int, @@ -84,10 +86,11 @@ object QueryExecutionAdvice { /** * Transfer context from msg to created result set so it can be used for further page fetches */ +class OnResultSetConstruction object OnResultSetConstruction { @Advice.OnMethodExit - def onCreateResultSet( + @static def onCreateResultSet( @Advice.Return rs: ArrayBackedResultSet, @Advice.Argument(0) msg: Responses.Result with HasContext ): Unit = if (rs.isInstanceOf[HasContext]) { @@ -96,24 +99,26 @@ object OnResultSetConstruction { } +class OnFetchMore object OnFetchMore { @Advice.OnMethodEnter - def onFetchMore(@Advice.This hasContext: HasContext): Scope = { + @static def onFetchMore(@Advice.This hasContext: HasContext): Scope = { val clientSpan = hasContext.context.get(QueryExecutionAdvice.ParentSpanKey) Kamon.storeContext(Context.of(Span.Key, clientSpan)) } @Advice.OnMethodExit - def onFetched(@Advice.Enter scope: Scope): Unit = { + @static def onFetched(@Advice.Enter scope: Scope): Unit = { scope.close() } } +class QueryWriteAdvice object QueryWriteAdvice { @Advice.OnMethodEnter - def onStartWriting(@Advice.This execution: HasContext): Unit = { + @static def onStartWriting(@Advice.This execution: HasContext): Unit = { execution.context .get(Span.Key) .mark("cassandra.connection.write-started") @@ -121,11 +126,12 @@ object QueryWriteAdvice { } //Server timeouts and exceptions +class OnSetAdvice object OnSetAdvice { import QueryOperations._ @Advice.OnMethodEnter - def onSetResult( + @static def onSetResult( @Advice.This execution: Connection.ResponseCallback with HasContext, @Advice.Argument(0) connection: Connection, @Advice.Argument(1) response: Message.Response, @@ -159,10 +165,11 @@ object OnSetAdvice { /** * Handling of client exceptions */ +class OnExceptionAdvice object OnExceptionAdvice { @Advice.OnMethodEnter - def onException( + @static def onException( @Advice.This execution: HasContext, @Advice.Argument(0) connection: Connection, @Advice.Argument(1) exception: Exception, @@ -181,10 +188,11 @@ object OnExceptionAdvice { /** * Handling of client timeouts */ +class OnTimeoutAdvice object OnTimeoutAdvice { @Advice.OnMethodEnter - def onTimeout( + @static def onTimeout( @Advice.This execution: HasContext, @Advice.Argument(0) connection: Connection, @Advice.FieldValue("current") currentHost: Host with HasPoolMetrics @@ -199,10 +207,11 @@ object OnTimeoutAdvice { } } +class HostLocationAdvice object HostLocationAdvice { @Advice.OnMethodExit - def onHostLocationUpdate( + @static def onHostLocationUpdate( @Advice.This host: Host with HasPoolMetrics, @Advice.FieldValue("manager") clusterManager: Any ): Unit = { diff --git a/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/SessionInterceptor.scala b/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/SessionInterceptor.scala index 62e06dcc7..6540b2aaf 100644 --- a/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/SessionInterceptor.scala +++ b/instrumentation/kamon-cassandra/src/main/scala/com/datastax/driver/core/SessionInterceptor.scala @@ -17,15 +17,16 @@ package com.datastax.driver.core import java.util.concurrent.Callable - import kamon.instrumentation.cassandra.driver.InstrumentedSession import kanela.agent.libs.net.bytebuddy.implementation.bind.annotation.{RuntimeType, SuperCall} +import scala.annotation.static + class SessionInterceptor object SessionInterceptor { @RuntimeType - def newSession(@SuperCall session: Callable[Session]): Session = { + @static def newSession(@SuperCall session: Callable[Session]): Session = { new InstrumentedSession(session.call()) } } diff --git a/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/driver/DriverInstrumentation.scala b/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/driver/DriverInstrumentation.scala index 4882d7396..e59e1c8c8 100644 --- a/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/driver/DriverInstrumentation.scala +++ b/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/driver/DriverInstrumentation.scala @@ -33,6 +33,7 @@ import kanela.agent.libs.net.bytebuddy.asm.Advice import java.util.concurrent.CompletionStage import java.util.function.BiConsumer +import scala.annotation.static class DriverInstrumentation extends InstrumentationBuilder { @@ -51,12 +52,12 @@ class DriverInstrumentation extends InstrumentationBuilder { */ onType("com.datastax.driver.core.HostConnectionPool") .advise(method("borrowConnection"), classOf[BorrowAdvice]) - .advise(method("trashConnection"), TrashConnectionAdvice) - .advise(method("addConnectionIfUnderMaximum"), CreateConnectionAdvice) - .advise(method("onConnectionDefunct"), ConnectionDefunctAdvice) - .advise(isConstructor, PoolConstructorAdvice) - .advise(method("initAsync"), InitPoolAdvice) - .advise(method("closeAsync"), PoolCloseAdvice) + .advise(method("trashConnection"), classOf[TrashConnectionAdvice]) + .advise(method("addConnectionIfUnderMaximum"), classOf[CreateConnectionAdvice]) + .advise(method("onConnectionDefunct"), classOf[ConnectionDefunctAdvice]) + .advise(isConstructor, classOf[PoolConstructorAdvice]) + .advise(method("initAsync"), classOf[InitPoolAdvice]) + .advise(method("closeAsync"), classOf[PoolCloseAdvice]) .mixin(classOf[HasPoolMetrics.Mixin]) /** @@ -66,18 +67,18 @@ class DriverInstrumentation extends InstrumentationBuilder { * to be used for further fetches */ onType("com.datastax.driver.core.RequestHandler$SpeculativeExecution") - .advise(method("query"), QueryExecutionAdvice) - .advise(method("write"), QueryWriteAdvice) - .advise(method("onException"), OnExceptionAdvice) - .advise(method("onTimeout"), OnTimeoutAdvice) - .advise(method("onSet"), OnSetAdvice) + .advise(method("query"), classOf[QueryExecutionAdvice]) + .advise(method("write"), classOf[QueryWriteAdvice]) + .advise(method("onException"), classOf[OnExceptionAdvice]) + .advise(method("onTimeout"), classOf[OnTimeoutAdvice]) + .advise(method("onSet"), classOf[OnSetAdvice]) .mixin(classOf[HasContext.MixinWithInitializer]) onSubTypesOf("com.datastax.driver.core.Message$Response") .mixin(classOf[HasContext.MixinWithInitializer]) onType("com.datastax.driver.core.ArrayBackedResultSet") - .advise(method("fromMessage"), OnResultSetConstruction) + .advise(method("fromMessage"), classOf[OnResultSetConstruction]) /** * In order for fetchMore execution to be a sibling of original execution @@ -86,7 +87,7 @@ class DriverInstrumentation extends InstrumentationBuilder { onType("com.datastax.driver.core.ArrayBackedResultSet$MultiPage") .mixin(classOf[HasContext.MixinWithInitializer]) onType("com.datastax.driver.core.ArrayBackedResultSet$MultiPage") - .advise(method("queryNextPage"), OnFetchMore) + .advise(method("queryNextPage"), classOf[OnFetchMore]) /** * Query metrics are tagged with target information (based on config) @@ -94,7 +95,7 @@ class DriverInstrumentation extends InstrumentationBuilder { */ onType("com.datastax.driver.core.Host") .mixin(classOf[HasPoolMetrics.Mixin]) - .advise(method("setLocationInfo"), HostLocationAdvice) + .advise(method("setLocationInfo"), classOf[HostLocationAdvice]) /** @@ -104,8 +105,8 @@ class DriverInstrumentation extends InstrumentationBuilder { "com.datastax.oss.driver.internal.core.cql.CqlPrepareHandler", "com.datastax.oss.driver.internal.core.cql.CqlRequestHandler") .mixin(classOf[HasContext.Mixin]) - .advise(isConstructor(), OnRequestHandlerConstructorAdvice) - .advise(method("onThrottleReady"), OnThrottleReadyAdvice) + .advise(isConstructor(), classOf[OnRequestHandlerConstructorAdvice]) + .advise(method("onThrottleReady"), classOf[OnThrottleReadyAdvice]) } @@ -116,10 +117,11 @@ object DriverInstrumentation { } } +class OnRequestHandlerConstructorAdvice object OnRequestHandlerConstructorAdvice { @Advice.OnMethodExit() - def exit(@Advice.This requestHandler: HasContext, @Advice.Argument(0) req: Any): Unit = { + @static def exit(@Advice.This requestHandler: HasContext, @Advice.Argument(0) req: Any): Unit = { val (operationName, statement) = req match { case pr: PrepareRequest => (QueryOperations.QueryPrepareOperationName, pr.getQuery()) case ss: cql.SimpleStatement => (QueryOperations.QueryOperationName, ss.getQuery()) @@ -158,10 +160,11 @@ object OnRequestHandlerConstructorAdvice { } } +class OnThrottleReadyAdvice object OnThrottleReadyAdvice { @Advice.OnMethodEnter() - def enter(@Advice.This requestHandler: HasContext): Unit = { + @static def enter(@Advice.This requestHandler: HasContext): Unit = { val querySpan = requestHandler.context.get(Span.Key) querySpan.mark("cassandra.throttle.ready") } diff --git a/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/executors/ExecutorInstrumentation.scala b/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/executors/ExecutorInstrumentation.scala index 77c9d7d0e..9d2552533 100644 --- a/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/executors/ExecutorInstrumentation.scala +++ b/instrumentation/kamon-cassandra/src/main/scala/kamon/instrumentation/cassandra/executors/ExecutorInstrumentation.scala @@ -17,24 +17,25 @@ package kamon.instrumentation.cassandra.executors import java.util.concurrent.{Callable, ExecutorService, ScheduledExecutorService} - import kamon.instrumentation.cassandra.CassandraInstrumentation import kamon.instrumentation.executor.ExecutorInstrumentation import kamon.tag.TagSet import kanela.agent.api.instrumentation.InstrumentationBuilder import kanela.agent.libs.net.bytebuddy.implementation.bind.annotation.SuperCall +import scala.annotation.static + class DriverExecutorInstrumentation extends InstrumentationBuilder { /** * Wraps all executors created by the Cassandra driver with the Kamon executors instrumentation. */ onType("com.datastax.driver.core.ThreadingOptions") - .intercept(method("createExecutor"), CreateExecutorAdvice) - .intercept(method("createBlockingExecutor"), CreateBlockingTasksExecutorAdvice) - .intercept(method("createReaperExecutor"), CreateReaperExecutorAdvice) - .intercept(method("createScheduledTasksExecutor"), CreateScheduledTasksExecutorAdvice) - .intercept(method("createReconnectionExecutor"), CreateReconnectionExecutorAdvice) + .intercept(method("createExecutor"), classOf[CreateExecutorAdvice]) + .intercept(method("createBlockingExecutor"), classOf[CreateBlockingTasksExecutorAdvice]) + .intercept(method("createReaperExecutor"), classOf[CreateReaperExecutorAdvice]) + .intercept(method("createScheduledTasksExecutor"), classOf[CreateScheduledTasksExecutorAdvice]) + .intercept(method("createReconnectionExecutor"), classOf[CreateReconnectionExecutorAdvice]) } sealed trait ExecutorMetrics { @@ -51,32 +52,37 @@ sealed trait ExecutorMetrics { ExecutorInstrumentation.instrumentScheduledExecutor(callable.call(), metricName(name), componentTags) } +class CreateExecutorAdvice object CreateExecutorAdvice extends ExecutorMetrics { - def onExecutorCreated(@SuperCall callable: Callable[ExecutorService]): ExecutorService = + @static def onExecutorCreated(@SuperCall callable: Callable[ExecutorService]): ExecutorService = instrument(callable, "executor") } +class CreateBlockingTasksExecutorAdvice object CreateBlockingTasksExecutorAdvice extends ExecutorMetrics { - def onExecutorCreated(@SuperCall callable: Callable[ExecutorService]): ExecutorService = + @static def onExecutorCreated(@SuperCall callable: Callable[ExecutorService]): ExecutorService = instrument(callable, "blocking") } +class CreateReaperExecutorAdvice object CreateReaperExecutorAdvice extends ExecutorMetrics { - def onExecutorCreated( + @static def onExecutorCreated( @SuperCall callable: Callable[ScheduledExecutorService] ): ScheduledExecutorService = instrumentScheduled(callable, "reaper") } +class CreateScheduledTasksExecutorAdvice object CreateScheduledTasksExecutorAdvice extends ExecutorMetrics { - def onExecutorCreated( + @static def onExecutorCreated( @SuperCall callable: Callable[ScheduledExecutorService] ): ScheduledExecutorService = instrumentScheduled(callable, "scheduled-tasks") } +class CreateReconnectionExecutorAdvice object CreateReconnectionExecutorAdvice extends ExecutorMetrics { - def onExecutorCreated( + @static def onExecutorCreated( @SuperCall callable: Callable[ScheduledExecutorService] ): ScheduledExecutorService = instrumentScheduled(callable, "reconnection") diff --git a/instrumentation/kamon-elasticsearch/src/test/scala/kamon/instrumentation/ElasticSearchInstrumentationTest.scala b/instrumentation/kamon-elasticsearch/src/test/scala/kamon/instrumentation/ElasticSearchInstrumentationTest.scala index 04bef44f6..462ce6138 100644 --- a/instrumentation/kamon-elasticsearch/src/test/scala/kamon/instrumentation/ElasticSearchInstrumentationTest.scala +++ b/instrumentation/kamon-elasticsearch/src/test/scala/kamon/instrumentation/ElasticSearchInstrumentationTest.scala @@ -85,7 +85,7 @@ class ElasticSearchInstrumentationTest } - override val container = ElasticsearchContainer() + override val container: ElasticsearchContainer = ElasticsearchContainer() var client: RestClient = _ var highLevelClient: RestHighLevelClient = _ @@ -95,7 +95,7 @@ class ElasticSearchInstrumentationTest client = RestClient .builder(HttpHost.create(container.httpHostAddress)) - .build + .build() highLevelClient = new RestHighLevelClient( RestClient.builder(HttpHost.create(container.httpHostAddress))) diff --git a/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/HikariInstrumentation.scala b/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/HikariInstrumentation.scala index 4b936e3a0..584ddc3b6 100644 --- a/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/HikariInstrumentation.scala +++ b/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/HikariInstrumentation.scala @@ -18,7 +18,6 @@ package kamon.instrumentation.jdbc import java.sql.{Connection, Statement} import java.util.concurrent.atomic.AtomicReference - import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.pool.{HikariPool, PoolEntry, PoolEntryProtectedAccess} import kamon.Kamon @@ -30,32 +29,33 @@ import kanela.agent.api.instrumentation.InstrumentationBuilder import kanela.agent.libs.net.bytebuddy.asm.Advice import kanela.agent.libs.net.bytebuddy.asm.Advice._ +import scala.annotation.static import scala.util.Try class HikariInstrumentation extends InstrumentationBuilder { onType("com.zaxxer.hikari.pool.HikariPool") .mixin(classOf[HasConnectionPoolTelemetry.Mixin]) - .advise(isConstructor(), HikariPoolConstructorAdvice) - .advise(method("checkFailFast"), CheckFailFastAdvice) - .advise(method("shutdown"), HikariPoolShutdownMethodAdvice) - .advise(method("createPoolEntry"), HikariPoolCreatePoolEntryMethodAdvice) - .advise(method("closeConnection"), HikariPoolCloseConnectionMethodAdvice) - .advise(method("createTimeoutException"), HikariPoolCreateTimeoutExceptionMethodAdvice) - .advise(method("getConnection").and(takesArguments(0)), HikariPoolGetConnectionAdvice) + .advise(isConstructor(), classOf[HikariPoolConstructorAdvice]) + .advise(method("checkFailFast"), classOf[CheckFailFastAdvice]) + .advise(method("shutdown"), classOf[HikariPoolShutdownMethodAdvice]) + .advise(method("createPoolEntry"), classOf[HikariPoolCreatePoolEntryMethodAdvice]) + .advise(method("closeConnection"), classOf[HikariPoolCloseConnectionMethodAdvice]) + .advise(method("createTimeoutException"), classOf[HikariPoolCreateTimeoutExceptionMethodAdvice]) + .advise(method("getConnection").and(takesArguments(0)), classOf[HikariPoolGetConnectionAdvice]) onType("com.zaxxer.hikari.pool.PoolBase") - .advise(method("setupConnection"), PoolBaseNewConnectionAdvice) + .advise(method("setupConnection"), classOf[PoolBaseNewConnectionAdvice]) onType("com.zaxxer.hikari.pool.PoolEntry") .mixin(classOf[HasConnectionPoolTelemetry.Mixin]) - .advise(method("createProxyConnection"), CreateProxyConnectionAdvice) + .advise(method("createProxyConnection"), classOf[CreateProxyConnectionAdvice]) onType("com.zaxxer.hikari.pool.ProxyConnection") - .advise(method("close"), ProxyConnectionCloseMethodAdvice) - .advise(method("createStatement"), ProxyConnectionStatementMethodsAdvice) - .advise(method("prepareStatement"), ProxyConnectionStatementMethodsAdvice) - .advise(method("prepareCall"), ProxyConnectionStatementMethodsAdvice) + .advise(method("close"), classOf[ProxyConnectionCloseMethodAdvice]) + .advise(method("createStatement"), classOf[ProxyConnectionStatementMethodsAdvice]) + .advise(method("prepareStatement"), classOf[ProxyConnectionStatementMethodsAdvice]) + .advise(method("prepareCall"), classOf[ProxyConnectionStatementMethodsAdvice]) } case class ConnectionPoolTelemetry(instruments: ConnectionPoolInstruments, databaseTags: DatabaseTags) @@ -73,18 +73,20 @@ object HasConnectionPoolTelemetry { } } +class CheckFailFastAdvice object CheckFailFastAdvice { @Advice.OnMethodEnter - def enter(@Advice.This hikariPool: Any): Unit = { + @static def enter(@Advice.This hikariPool: Any): Unit = { hikariPool.asInstanceOf[HasConnectionPoolTelemetry].setConnectionPoolTelemetry(new AtomicReference[ConnectionPoolTelemetry]()) } } +class HikariPoolConstructorAdvice object HikariPoolConstructorAdvice { @Advice.OnMethodExit - def exit(@Advice.This hikariPool: HasConnectionPoolTelemetry, @Advice.Argument(0) config: HikariConfig): Unit = { + @static def exit(@Advice.This hikariPool: HasConnectionPoolTelemetry, @Advice.Argument(0) config: HikariConfig): Unit = { val url = config.getJdbcUrl() val vendor = Try(url.split(':')(1)).getOrElse("unknown") @@ -103,17 +105,19 @@ object HikariPoolConstructorAdvice { } } +class HikariPoolShutdownMethodAdvice object HikariPoolShutdownMethodAdvice { @Advice.OnMethodExit - def exit(@This hikariPool: Object): Unit = + @static def exit(@This hikariPool: Object): Unit = hikariPool.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry.get.instruments.remove() } +class HikariPoolCreatePoolEntryMethodAdvice object HikariPoolCreatePoolEntryMethodAdvice { @Advice.OnMethodExit - def exit(@This hikariPool: HasConnectionPoolTelemetry, @Advice.Return poolEntry: Any): Unit = { + @static def exit(@This hikariPool: HasConnectionPoolTelemetry, @Advice.Return poolEntry: Any): Unit = { if(hikariPool != null && poolEntry != null) { poolEntry.asInstanceOf[HasConnectionPoolTelemetry].setConnectionPoolTelemetry(hikariPool.connectionPoolTelemetry) @@ -125,33 +129,37 @@ object HikariPoolCreatePoolEntryMethodAdvice { } } +class HikariPoolCloseConnectionMethodAdvice object HikariPoolCloseConnectionMethodAdvice { @Advice.OnMethodExit - def exit(@This hikariPool: Any): Unit = { + @static def exit(@This hikariPool: Any): Unit = { hikariPool.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry.get.instruments.openConnections.decrement() } } +class HikariPoolCreateTimeoutExceptionMethodAdvice object HikariPoolCreateTimeoutExceptionMethodAdvice { @Advice.OnMethodExit - def exit(@This hikariPool: Any): Unit = + @static def exit(@This hikariPool: Any): Unit = hikariPool.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry.get.instruments.borrowTimeouts.increment() } +class ProxyConnectionCloseMethodAdvice object ProxyConnectionCloseMethodAdvice { @Advice.OnMethodExit - def exit(@This proxyConnection: Any): Unit = { + @static def exit(@This proxyConnection: Any): Unit = { proxyConnection.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry.get.instruments.borrowedConnections.decrement() } } +class ProxyConnectionStatementMethodsAdvice object ProxyConnectionStatementMethodsAdvice { @Advice.OnMethodExit - def exit(@This proxyConnection: Any, @Return statement: Statement): Unit = { + @static def exit(@This proxyConnection: Any, @Return statement: Statement): Unit = { val poolTracker = proxyConnection.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry statement @@ -162,15 +170,16 @@ object ProxyConnectionStatementMethodsAdvice { } } +class HikariPoolGetConnectionAdvice object HikariPoolGetConnectionAdvice { @Advice.OnMethodEnter - def executeStart(): Long = { + @static def executeStart(): Long = { System.nanoTime() } @Advice.OnMethodExit(onThrowable = classOf[Exception]) - def executeEnd(@Advice.Enter startTime: Long, @Advice.Return connection: Connection, @Advice.This pool: HasConnectionPoolTelemetry, + @static def executeEnd(@Advice.Enter startTime: Long, @Advice.Return connection: Connection, @Advice.This pool: HasConnectionPoolTelemetry, @Advice.Thrown throwable: java.lang.Throwable): Unit = { val borrowTime = System.nanoTime() - startTime @@ -187,25 +196,27 @@ object HikariPoolGetConnectionAdvice { } } +class PoolBaseNewConnectionAdvice object PoolBaseNewConnectionAdvice { import Hooks.PreStart @Advice.OnMethodEnter - def enter(@Advice.This pool: Any, @Advice.Argument(0) connection: Any): Scope = { + @static def enter(@Advice.This pool: Any, @Advice.Argument(0) connection: Any): Scope = { connection.asInstanceOf[HasConnectionPoolTelemetry].setConnectionPoolTelemetry(pool.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry) Kamon.storeContext(Kamon.currentContext().withEntry(PreStart.Key, PreStart.updateOperationName("init"))) } @Advice.OnMethodExit - def exit(@Advice.Enter scope: Scope): Unit = { + @static def exit(@Advice.Enter scope: Scope): Unit = { scope.close() } } +class CreateProxyConnectionAdvice object CreateProxyConnectionAdvice { @Advice.OnMethodExit - def exit(@Advice.This poolEntry: Any): Unit = { + @static def exit(@Advice.This poolEntry: Any): Unit = { val realConnection = PoolEntryProtectedAccess.underlyingConnection(poolEntry) if(realConnection != null) { realConnection.asInstanceOf[HasConnectionPoolTelemetry].setConnectionPoolTelemetry(poolEntry.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry) diff --git a/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/StatementInstrumentation.scala b/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/StatementInstrumentation.scala index f86081fd9..3acb540d6 100644 --- a/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/StatementInstrumentation.scala +++ b/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/StatementInstrumentation.scala @@ -18,7 +18,6 @@ package kamon.instrumentation.jdbc import java.sql.PreparedStatement import java.util.Properties - import kamon.Kamon import kamon.context.Storage.Scope import kamon.instrumentation.jdbc.advisor._ @@ -31,6 +30,8 @@ import kanela.agent.libs.net.bytebuddy.asm.Advice import scala.util.Try import kanela.agent.libs.net.bytebuddy.matcher.ElementMatchers._ +import scala.annotation.static + class StatementInstrumentation extends InstrumentationBuilder { private val withOneStringArgument = withArgument(0, classOf[String]) @@ -123,10 +124,11 @@ object HasStatementSQL { } } +class DriverConnectAdvice object DriverConnectAdvice { @Advice.OnMethodExit - def exit(@Advice.Argument(0) url: String, @Advice.Argument(1) properties: Properties, @Advice.Return connection: Any): Unit = { + @static def exit(@Advice.Argument(0) url: String, @Advice.Argument(1) properties: Properties, @Advice.Return connection: Any): Unit = { // The connection could be null if there is more than one registered driver and the DriverManager is looping // through them to figure out which one accepts the URL. @@ -147,38 +149,42 @@ object DriverConnectAdvice { } } +class CreateStatementAdvice object CreateStatementAdvice { @Advice.OnMethodExit - def exit(@Advice.This connection: Any, @Advice.Return statement: Any): Unit = { + @static def exit(@Advice.This connection: Any, @Advice.Return statement: Any): Unit = { statement.asInstanceOf[HasDatabaseTags].setDatabaseTags(connection.asInstanceOf[HasDatabaseTags].databaseTags()) statement.asInstanceOf[HasConnectionPoolTelemetry].setConnectionPoolTelemetry(connection.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry) } } +class CreatePreparedStatementAdvice object CreatePreparedStatementAdvice { @Advice.OnMethodExit - def exit(@Advice.This connection: Any, @Advice.Argument(0) sql: String, @Advice.Return statement: Any): Unit = { + @static def exit(@Advice.This connection: Any, @Advice.Argument(0) sql: String, @Advice.Return statement: Any): Unit = { statement.asInstanceOf[HasDatabaseTags].setDatabaseTags(connection.asInstanceOf[HasDatabaseTags].databaseTags()) statement.asInstanceOf[HasConnectionPoolTelemetry].setConnectionPoolTelemetry(statement.asInstanceOf[HasConnectionPoolTelemetry].connectionPoolTelemetry) statement.asInstanceOf[HasStatementSQL].setStatementSQL(sql) } } +class ConnectionIsValidAdvice object ConnectionIsValidAdvice { import Hooks.PreStart @Advice.OnMethodEnter - def enter(): Scope = + @static def enter(): Scope = Kamon.storeContext(Kamon.currentContext().withEntry(PreStart.Key, PreStart.updateOperationName("isValid"))) @Advice.OnMethodExit - def exit(@Advice.Enter scope: Scope): Unit = + @static def exit(@Advice.Enter scope: Scope): Unit = scope.close() } +class PgConnectionIsAliveAdvice object PgConnectionIsAliveAdvice { trait PgConnectionPrivateAccess { @@ -188,7 +194,7 @@ object PgConnectionIsAliveAdvice { } @Advice.OnMethodEnter - def enter(@Advice.This connection: Any): Unit = { + @static def enter(@Advice.This connection: Any): Unit = { if(connection != null) { val statement = connection.asInstanceOf[PgConnectionPrivateAccess].getCheckConnectionStatement() diff --git a/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/advisor/StatementInstrumentationAdvisors.scala b/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/advisor/StatementInstrumentationAdvisors.scala index 4075a1d6a..5096ea334 100644 --- a/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/advisor/StatementInstrumentationAdvisors.scala +++ b/instrumentation/kamon-jdbc/src/main/scala/kamon/instrumentation/jdbc/advisor/StatementInstrumentationAdvisors.scala @@ -17,24 +17,25 @@ package kamon.instrumentation.jdbc.advisor import java.sql.{PreparedStatement, Statement} - import kamon.instrumentation.jdbc.{HasStatementSQL, StatementMonitor} import kamon.instrumentation.jdbc.StatementMonitor.{Invocation, StatementTypes} import kanela.agent.libs.net.bytebuddy.asm.Advice import kanela.agent.libs.net.bytebuddy.asm.Advice.Thrown +import scala.annotation.static + /** * Advisor for java.sql.Statement::execute */ class StatementExecuteMethodAdvisor object StatementExecuteMethodAdvisor { @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def executeStart(@Advice.This statement: Any, @Advice.Argument(0) sql: String): Option[Invocation] = { + @static def executeStart(@Advice.This statement: Any, @Advice.Argument(0) sql: String): Option[Invocation] = { StatementMonitor.start(statement, sql, StatementTypes.GenericExecute) } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { + @static def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { invocation.foreach(_.close(throwable)) } } @@ -45,12 +46,12 @@ object StatementExecuteMethodAdvisor { class PreparedStatementExecuteMethodAdvisor object PreparedStatementExecuteMethodAdvisor { @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def executeStart(@Advice.This statement: HasStatementSQL): Option[Invocation] = { + @static def executeStart(@Advice.This statement: HasStatementSQL): Option[Invocation] = { StatementMonitor.start(statement, statement.capturedStatementSQL(), StatementTypes.GenericExecute) } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { + @static def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { invocation.foreach(_.close(throwable)) } } @@ -62,12 +63,12 @@ object PreparedStatementExecuteMethodAdvisor { class StatementExecuteQueryMethodAdvisor object StatementExecuteQueryMethodAdvisor { @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def executeStart(@Advice.This statement: Any, @Advice.Argument(0) sql: String): Option[Invocation] = { + @static def executeStart(@Advice.This statement: Any, @Advice.Argument(0) sql: String): Option[Invocation] = { StatementMonitor.start(statement, sql, StatementTypes.Query) } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { + @static def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { invocation.foreach(_.close(throwable)) } } @@ -78,12 +79,12 @@ object StatementExecuteQueryMethodAdvisor { class PreparedStatementExecuteQueryMethodAdvisor object PreparedStatementExecuteQueryMethodAdvisor { @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def executeStart(@Advice.This statement: HasStatementSQL): Option[Invocation] = { + @static def executeStart(@Advice.This statement: HasStatementSQL): Option[Invocation] = { StatementMonitor.start(statement, statement.capturedStatementSQL(), StatementTypes.Query) } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { + @static def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { invocation.foreach(_.close(throwable)) } } @@ -94,12 +95,12 @@ object PreparedStatementExecuteQueryMethodAdvisor { class StatementExecuteUpdateMethodAdvisor object StatementExecuteUpdateMethodAdvisor { @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def executeStart(@Advice.This statement: Any, @Advice.Argument(0) sql: String): Option[Invocation] = { + @static def executeStart(@Advice.This statement: Any, @Advice.Argument(0) sql: String): Option[Invocation] = { StatementMonitor.start(statement, sql, StatementTypes.Update) } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { + @static def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { invocation.foreach(_.close(throwable)) } } @@ -110,12 +111,12 @@ object StatementExecuteUpdateMethodAdvisor { class PreparedStatementExecuteUpdateMethodAdvisor object PreparedStatementExecuteUpdateMethodAdvisor { @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def executeStart(@Advice.This statement: HasStatementSQL): Option[Invocation] = { + @static def executeStart(@Advice.This statement: HasStatementSQL): Option[Invocation] = { StatementMonitor.start(statement, statement.capturedStatementSQL(), StatementTypes.Update) } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { + @static def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { invocation.foreach(_.close(throwable)) } } @@ -128,7 +129,7 @@ class StatementExecuteBatchMethodAdvisor object StatementExecuteBatchMethodAdvisor { // inline @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def executeStart(@Advice.This statement: Any): Option[Invocation] = { + @static def executeStart(@Advice.This statement: Any): Option[Invocation] = { val statementSQL = statement match { case hSQL: HasStatementSQL => hSQL.capturedStatementSQL() case _ => statement.toString @@ -138,7 +139,7 @@ object StatementExecuteBatchMethodAdvisor { } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { + @static def executeEnd(@Advice.Enter invocation: Option[Invocation], @Thrown throwable: Throwable): Unit = { invocation.foreach(_.close(throwable)) } } diff --git a/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/HikariInstrumentationSpec.scala b/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/HikariInstrumentationSpec.scala index 024bc3368..b60dfd603 100644 --- a/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/HikariInstrumentationSpec.scala +++ b/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/HikariInstrumentationSpec.scala @@ -17,7 +17,6 @@ package kamon.instrumentation.jdbc import java.sql.SQLException import java.util.concurrent.Executors - import com.typesafe.config.ConfigFactory import com.zaxxer.hikari.{HikariConfig, HikariDataSource} import kamon.Kamon @@ -30,7 +29,7 @@ import org.scalatest.time.SpanSugar import org.scalatest.wordspec.AnyWordSpec import org.scalatest.{BeforeAndAfterEach, OptionValues} -import scala.concurrent.ExecutionContext +import scala.concurrent.{ExecutionContext, ExecutionContextExecutor} class HikariInstrumentationSpec extends AnyWordSpec with Matchers @@ -44,7 +43,7 @@ class HikariInstrumentationSpec extends AnyWordSpec with OptionValues { import HikariInstrumentationSpec.{createH2Pool, createSQLitePool} - implicit val parallelQueriesContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(16)) + implicit val parallelQueriesContext: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(16)) override def beforeEach() = testSpanReporter().clear() diff --git a/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/StatementInstrumentationSpec.scala b/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/StatementInstrumentationSpec.scala index 6100b0a46..e42604917 100644 --- a/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/StatementInstrumentationSpec.scala +++ b/instrumentation/kamon-jdbc/src/test/scala/kamon/instrumentation/jdbc/StatementInstrumentationSpec.scala @@ -32,7 +32,7 @@ import org.scalatest.{BeforeAndAfterEach, OptionValues} import java.sql.{Connection, DriverManager, ResultSet} import java.time.Duration import java.util.concurrent.Executors -import scala.concurrent.{ExecutionContext, Future} +import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future} import scala.util.{Failure, Success, Try} class StatementInstrumentationSpec extends AnyWordSpec @@ -47,7 +47,7 @@ class StatementInstrumentationSpec extends AnyWordSpec with InitAndStopKamonAfterAll with TestSpanReporter { - implicit val parallelQueriesExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10)) + implicit val parallelQueriesExecutor: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10)) override protected def beforeAll(): Unit = { diff --git a/instrumentation/kamon-logback/src/main/scala/kamon/instrumentation/logback/LogbackInstrumentation.scala b/instrumentation/kamon-logback/src/main/scala/kamon/instrumentation/logback/LogbackInstrumentation.scala index 78eb60ec0..595c8ae6e 100644 --- a/instrumentation/kamon-logback/src/main/scala/kamon/instrumentation/logback/LogbackInstrumentation.scala +++ b/instrumentation/kamon-logback/src/main/scala/kamon/instrumentation/logback/LogbackInstrumentation.scala @@ -29,6 +29,7 @@ import kanela.agent.libs.net.bytebuddy.implementation.bind.annotation.{RuntimeTy import org.slf4j.MDC import java.util.concurrent.Callable +import scala.annotation.static import scala.collection.JavaConverters._ @@ -38,10 +39,10 @@ class LogbackInstrumentation extends InstrumentationBuilder { .mixin(classOf[HasContext.MixinWithInitializer]) onType("ch.qos.logback.core.spi.AppenderAttachableImpl") - .advise(method("appendLoopOnAppenders"), AppendLoopOnAppendersAdvice) + .advise(method("appendLoopOnAppenders"), classOf[AppendLoopOnAppendersAdvice]) onType("ch.qos.logback.classic.spi.LoggingEvent") - .intercept(method("getMDCPropertyMap"), GetPropertyMapMethodInterceptor) + .intercept(method("getMDCPropertyMap"), classOf[GetPropertyMapMethodInterceptor]) } object LogbackInstrumentation { @@ -77,21 +78,23 @@ object LogbackInstrumentation { } } +class AppendLoopOnAppendersAdvice object AppendLoopOnAppendersAdvice { @Advice.OnMethodEnter - def enter(@Advice.Argument(0) event: Any): Scope = + @static def enter(@Advice.Argument(0) event: Any): Scope = Kamon.storeContext(event.asInstanceOf[HasContext].context) @Advice.OnMethodExit - def exit(@Advice.Enter scope: Scope): Unit = + @static def exit(@Advice.Enter scope: Scope): Unit = scope.close() } +class GetPropertyMapMethodInterceptor object GetPropertyMapMethodInterceptor { @RuntimeType - def aroundGetMDCPropertyMap(@SuperCall callable: Callable[_]): Any = { + @static def aroundGetMDCPropertyMap(@SuperCall callable: Callable[_]): Any = { val settings = LogbackInstrumentation.settings() if (settings.propagateContextToMDC) { diff --git a/instrumentation/kamon-okhttp/src/main/scala/kamon/okhttp3/instrumentation/OkHttpInstrumentation.scala b/instrumentation/kamon-okhttp/src/main/scala/kamon/okhttp3/instrumentation/OkHttpInstrumentation.scala index b9a2639ff..fc5d0ef51 100644 --- a/instrumentation/kamon-okhttp/src/main/scala/kamon/okhttp3/instrumentation/OkHttpInstrumentation.scala +++ b/instrumentation/kamon-okhttp/src/main/scala/kamon/okhttp3/instrumentation/OkHttpInstrumentation.scala @@ -20,6 +20,8 @@ import kanela.agent.api.instrumentation.InstrumentationBuilder import kanela.agent.libs.net.bytebuddy.asm.Advice import okhttp3.OkHttpClient +import scala.annotation.static + class OkHttpInstrumentation extends InstrumentationBuilder { /** @@ -41,7 +43,7 @@ object OkHttpClientBuilderAdvisor { import scala.collection.JavaConverters._ @Advice.OnMethodEnter(suppress = classOf[Throwable]) - def addKamonInterceptor(@Advice.Argument(0) builder: OkHttpClient.Builder): Unit = { + @static def addKamonInterceptor(@Advice.Argument(0) builder: OkHttpClient.Builder): Unit = { val interceptors = builder.networkInterceptors.asScala if (!interceptors.exists(_.isInstanceOf[KamonTracingInterceptor])) { builder.addNetworkInterceptor(new KamonTracingInterceptor) diff --git a/instrumentation/kamon-okhttp/src/test/scala/kamon/okhttp3/instrumentation/OkHttpTracingInstrumentationSpec.scala b/instrumentation/kamon-okhttp/src/test/scala/kamon/okhttp3/instrumentation/OkHttpTracingInstrumentationSpec.scala index 8c806fd30..be5b29ff8 100644 --- a/instrumentation/kamon-okhttp/src/test/scala/kamon/okhttp3/instrumentation/OkHttpTracingInstrumentationSpec.scala +++ b/instrumentation/kamon-okhttp/src/test/scala/kamon/okhttp3/instrumentation/OkHttpTracingInstrumentationSpec.scala @@ -36,7 +36,6 @@ class OkHttpTracingInstrumentationSpec extends AnyWordSpec with Matchers with Eventually with SpanSugar - with InitAndStopKamonAfterAll with BeforeAndAfterEach with TestSpanReporter with JettySupport @@ -281,6 +280,7 @@ class OkHttpTracingInstrumentationSpec extends AnyWordSpec } override protected def beforeAll(): Unit = { + Kamon.init() super.beforeAll() applyConfig( s""" @@ -293,8 +293,6 @@ class OkHttpTracingInstrumentationSpec extends AnyWordSpec | } |} |""".stripMargin) - enableFastSpanFlushing() - sampleAlways() startServer() } @@ -302,6 +300,7 @@ class OkHttpTracingInstrumentationSpec extends AnyWordSpec override protected def afterAll(): Unit = { stopServer() super.afterAll() + Kamon.stop() } override protected def beforeEach(): Unit = { diff --git a/instrumentation/kamon-spring/src/main/scala/kamon/instrumentation/spring/server/SpringMVCInstrumentation.scala b/instrumentation/kamon-spring/src/main/scala/kamon/instrumentation/spring/server/SpringMVCInstrumentation.scala index 6c8e298b5..e5e291fdf 100644 --- a/instrumentation/kamon-spring/src/main/scala/kamon/instrumentation/spring/server/SpringMVCInstrumentation.scala +++ b/instrumentation/kamon-spring/src/main/scala/kamon/instrumentation/spring/server/SpringMVCInstrumentation.scala @@ -26,6 +26,7 @@ import org.springframework.web.servlet.HandlerMapping import java.util.concurrent.Callable import javax.servlet.http.{HttpServletRequest, HttpServletResponse} +import scala.annotation.static class SpringMVCInstrumentation extends InstrumentationBuilder { @@ -35,10 +36,10 @@ class SpringMVCInstrumentation extends InstrumentationBuilder { */ onType("org.springframework.web.servlet.DispatcherServlet") .mixin(classOf[HasServerInstrumentation.Mixin]) - .advise(method("doDispatch"), DispatchAdvice) - .advise(method("render"), RenderAdvice) - .advise(method("processHandlerException"), ProcessHandlerExceptionAdvice) - .advise(method("getHandler").and(takesArguments(1)), GetHandlerAdvice) + .advise(method("doDispatch"), classOf[DispatchAdvice]) + .advise(method("render"), classOf[RenderAdvice]) + .advise(method("processHandlerException"), classOf[ProcessHandlerExceptionAdvice]) + .advise(method("getHandler").and(takesArguments(1)), classOf[GetHandlerAdvice]) /* * Changes Callable argument of startCallableProcessing with an @@ -50,9 +51,10 @@ class SpringMVCInstrumentation extends InstrumentationBuilder { .and(withArgument(0, classOf[Callable[_]])), classOf[CallableWrapper]) } +class DispatchAdvice object DispatchAdvice { @Advice.OnMethodEnter() - def enter(@Advice.This dispatcherServlet: HasServerInstrumentation, + @static def enter(@Advice.This dispatcherServlet: HasServerInstrumentation, @Advice.Argument(0) request: HttpServletRequest): (RequestHandler, Scope) = { val requestHandler = Option(request.getAttribute("kamon-handler").asInstanceOf[RequestHandler]) .getOrElse({ @@ -68,7 +70,7 @@ object DispatchAdvice { } @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def exit(@Advice.Enter enter: (RequestHandler, Scope), + @static def exit(@Advice.Enter enter: (RequestHandler, Scope), @Advice.Argument(0) request: HttpServletRequest, @Advice.Argument(1) response: HttpServletResponse): Unit = { val (handler, scope) = enter @@ -83,9 +85,10 @@ object DispatchAdvice { } } +class GetHandlerAdvice object GetHandlerAdvice { @Advice.OnMethodExit() - def exit(@Advice.Argument(0) request: HttpServletRequest): Unit = { + @static def exit(@Advice.Argument(0) request: HttpServletRequest): Unit = { val handler = request.getAttribute("kamon-handler").asInstanceOf[RequestHandler] val pattern = request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE) @@ -96,21 +99,23 @@ object GetHandlerAdvice { } } +class ProcessHandlerExceptionAdvice object ProcessHandlerExceptionAdvice { @Advice.OnMethodExit(onThrowable = classOf[Throwable], suppress = classOf[Throwable]) - def exit(@Advice.Argument(3) throwable: Throwable): Unit = { + @static def exit(@Advice.Argument(3) throwable: Throwable): Unit = { if (throwable != null) { Kamon.currentSpan().fail(throwable) } } } +class RenderAdvice object RenderAdvice { @Advice.OnMethodEnter() - def enter(): Span = + @static def enter(): Span = Kamon.internalSpanBuilder("view.render", "spring.server").start() @Advice.OnMethodExit() - def exit(@Advice.Enter span: Span): Unit = + @static def exit(@Advice.Enter span: Span): Unit = span.finish() } diff --git a/project/Build.scala b/project/Build.scala index cbe479060..a11232688 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -138,7 +138,8 @@ object BaseProject extends AutoPlugin { crossScalaVersions := Seq( autoImport.`scala_2.11_version`, autoImport.`scala_2.12_version`, - autoImport.`scala_2.13_version` + autoImport.`scala_2.13_version`, + autoImport.`scala_3_version` ), javacOptions := Seq( "-source", "1.8",