From 9b18d1d2dbee7450786a7310472100c0cda9152c Mon Sep 17 00:00:00 2001 From: Wojciech Langiewicz Date: Wed, 6 Oct 2021 10:41:07 +0200 Subject: [PATCH 1/3] routine project cleanup --- .github/workflows/scala.yml | 4 +++- .gitignore | 2 +- build.sbt | 16 ++++++++-------- project/build.properties | 2 +- project/plugins.sbt | 6 +++--- .../api/MetricFamilySamplesEntity.scala | 6 +++--- .../http/prometheus/api/MetricsEndpoint.scala | 3 ++- .../ResponseTimeRecordingDirectives.scala | 4 ++-- .../prometheus/PrometheusEventObserverSpec.scala | 6 +++--- .../PrometheusResponseTimeRecorderSpec.scala | 4 ++-- .../prometheus/api/MetricsEndpointSpec.scala | 3 +-- 11 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index db87f1c..bd63367 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -10,7 +10,9 @@ jobs: - name: Checkout uses: actions/checkout@v2 - name: Set up Scala - uses: olafurpg/setup-scala@v10 + uses: olafurpg/setup-scala@v11 + with: + java-version: openjdk@1.14 - name: Cache sbt uses: actions/cache@v2 with: diff --git a/.gitignore b/.gitignore index b43f254..24b1f35 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ # Artifacts target project/project - +.bsp diff --git a/build.sbt b/build.sbt index 00f978e..b81ae3e 100644 --- a/build.sbt +++ b/build.sbt @@ -6,14 +6,14 @@ publishTo := sonatypePublishToBundle.value version := "0.5.2-SNAPSHOT" -scalaVersion := "2.13.5" +scalaVersion := "2.13.6" libraryDependencies ++= { - val simpleclientVersion = "0.8.1" - val akkaVersion = "2.6.14" - val akkaHttpVersion = "10.2.4" - val scalaTestVersion = "3.1.4" - val scalamockVersion = "4.4.0" + val simpleclientVersion = "0.12.0" + val akkaVersion = "2.6.16" + val akkaHttpVersion = "10.2.6" + val scalaTestVersion = "3.2.10" + val scalamockVersion = "5.1.0" Seq( "com.typesafe.akka" %% "akka-actor" % akkaVersion % Provided, @@ -32,6 +32,6 @@ libraryDependencies ++= { lazy val `root` = (project in file(".")) .settings( addCommandAlias("testAll", ";test"), - addCommandAlias("formatAll", ";scalafmt;test:scalafmt;scalafmtSbt"), - addCommandAlias("compileAll", ";compile;test:compile") + addCommandAlias("formatAll", ";scalafmt;Test/scalafmt;scalafmtSbt"), + addCommandAlias("compileAll", ";compile;Test/compile") ) diff --git a/project/build.properties b/project/build.properties index 63527fe..215ddd2 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version = 1.5.1 \ No newline at end of file +sbt.version = 1.5.5 \ No newline at end of file diff --git a/project/plugins.sbt b/project/plugins.sbt index a67dde0..2102fed 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ logLevel := Level.Warn -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.7") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.10") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") -addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.16") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") +addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.20") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3") diff --git a/src/main/scala/com/varwise/akka/http/prometheus/api/MetricFamilySamplesEntity.scala b/src/main/scala/com/varwise/akka/http/prometheus/api/MetricFamilySamplesEntity.scala index 80fc2cb..41fb779 100644 --- a/src/main/scala/com/varwise/akka/http/prometheus/api/MetricFamilySamplesEntity.scala +++ b/src/main/scala/com/varwise/akka/http/prometheus/api/MetricFamilySamplesEntity.scala @@ -1,14 +1,14 @@ package com.varwise.akka.http.prometheus.api -import java.io.{StringWriter, Writer} -import java.util - import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller} import akka.http.scaladsl.model._ import io.prometheus.client.Collector.MetricFamilySamples import io.prometheus.client.CollectorRegistry import io.prometheus.client.exporter.common.TextFormat +import java.io.{StringWriter, Writer} +import java.util + case class MetricFamilySamplesEntity(samples: util.Enumeration[MetricFamilySamples]) object MetricFamilySamplesEntity { diff --git a/src/main/scala/com/varwise/akka/http/prometheus/api/MetricsEndpoint.scala b/src/main/scala/com/varwise/akka/http/prometheus/api/MetricsEndpoint.scala index 06624ca..29604bc 100644 --- a/src/main/scala/com/varwise/akka/http/prometheus/api/MetricsEndpoint.scala +++ b/src/main/scala/com/varwise/akka/http/prometheus/api/MetricsEndpoint.scala @@ -1,11 +1,12 @@ package com.varwise.akka.http.prometheus.api import akka.http.scaladsl.server.Directives._ +import akka.http.scaladsl.server.Route import io.prometheus.client.CollectorRegistry class MetricsEndpoint(registry: CollectorRegistry) { - val routes = { + val routes: Route = { get { path("metrics") { complete { diff --git a/src/main/scala/com/varwise/akka/http/prometheus/directives/ResponseTimeRecordingDirectives.scala b/src/main/scala/com/varwise/akka/http/prometheus/directives/ResponseTimeRecordingDirectives.scala index bc0269c..9d9e333 100644 --- a/src/main/scala/com/varwise/akka/http/prometheus/directives/ResponseTimeRecordingDirectives.scala +++ b/src/main/scala/com/varwise/akka/http/prometheus/directives/ResponseTimeRecordingDirectives.scala @@ -1,7 +1,7 @@ package com.varwise.akka.http.prometheus.directives -import akka.http.scaladsl.server.{Directive, ExceptionHandler} import akka.http.scaladsl.server.directives.{BasicDirectives, ExecutionDirectives} +import akka.http.scaladsl.server.{Directive, ExceptionHandler} import com.varwise.akka.http.prometheus.ResponseTimeRecorder import scala.concurrent.duration @@ -46,7 +46,7 @@ trait ResponseTimeRecordingDirectives { object ResponseTimeRecordingDirectives { - def apply(r: ResponseTimeRecorder) = + def apply(r: ResponseTimeRecorder): ResponseTimeRecordingDirectives = new ResponseTimeRecordingDirectives with ResponseTimeRecorderProvider { override def recorder: ResponseTimeRecorder = r } diff --git a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusEventObserverSpec.scala b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusEventObserverSpec.scala index 800d8dd..5d1f5a6 100644 --- a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusEventObserverSpec.scala +++ b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusEventObserverSpec.scala @@ -1,6 +1,6 @@ package com.varwise.akka.http.prometheus -import Utils._ +import com.varwise.akka.http.prometheus.Utils._ import io.prometheus.client.CollectorRegistry import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers @@ -25,9 +25,9 @@ class PrometheusEventObserverSpec extends AnyFlatSpec with Matchers { registry ) - def getCounterValue = + def getCounterValue: java.lang.Double = registry.getSampleValue( - randomMetricName, + randomMetricName + "_total", Array(randomEventLabelName, randomEventDetailsLabelName), Array(randomEventName, randomEventDetails) ) diff --git a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala index 6657ea3..6a3d1e4 100644 --- a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala +++ b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala @@ -1,8 +1,8 @@ package com.varwise.akka.http.prometheus +import com.varwise.akka.http.prometheus.Utils._ import io.prometheus.client.{Collector, CollectorRegistry} import org.scalamock.scalatest.MockFactory -import Utils._ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers @@ -57,7 +57,7 @@ class PrometheusResponseTimeRecorderSpec extends AnyFlatSpec with Matchers with labelNames: List[String], labelValues: List[String], bucket: Double - ) = { + ): Int = { val name = metricName + "_bucket" // 'le' should be the first label in the list diff --git a/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala b/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala index ec57257..c77edbe 100644 --- a/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala +++ b/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala @@ -1,7 +1,5 @@ package com.varwise.akka.http.prometheus.api -import java.io.StringWriter - import akka.http.scaladsl.model.HttpCharsets import akka.http.scaladsl.testkit.ScalatestRouteTest import com.varwise.akka.http.prometheus.Utils._ @@ -10,6 +8,7 @@ import io.prometheus.client.{CollectorRegistry, Histogram} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers +import java.io.StringWriter import scala.util.Random class MetricsEndpointSpec extends AnyFlatSpec with Matchers with ScalatestRouteTest { From 6b3f9cae26bed70f544e395b44d19468d40f8c7c Mon Sep 17 00:00:00 2001 From: Wojciech Langiewicz Date: Wed, 6 Oct 2021 12:37:20 +0200 Subject: [PATCH 2/3] remove scalamock, add scala 3 cross building --- build.sbt | 26 ++++++++++--------- .../PrometheusResponseTimeRecorderSpec.scala | 3 +-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/build.sbt b/build.sbt index b81ae3e..5e0fee5 100644 --- a/build.sbt +++ b/build.sbt @@ -6,26 +6,28 @@ publishTo := sonatypePublishToBundle.value version := "0.5.2-SNAPSHOT" -scalaVersion := "2.13.6" +val scala2Version = "2.13.6" +val scala3Version = "3.0.2" + +scalaVersion := scala3Version +crossScalaVersions := Seq(scala3Version, scala2Version) libraryDependencies ++= { val simpleclientVersion = "0.12.0" val akkaVersion = "2.6.16" val akkaHttpVersion = "10.2.6" val scalaTestVersion = "3.2.10" - val scalamockVersion = "5.1.0" Seq( - "com.typesafe.akka" %% "akka-actor" % akkaVersion % Provided, - "com.typesafe.akka" %% "akka-stream" % akkaVersion % Provided, - "com.typesafe.akka" %% "akka-http" % akkaHttpVersion % Provided, - "com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion % Provided, - "io.prometheus" % "simpleclient" % simpleclientVersion, - "io.prometheus" % "simpleclient_common" % simpleclientVersion, - "org.scalamock" %% "scalamock" % scalamockVersion % Test, - "com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test, - "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test, - "org.scalatest" %% "scalatest" % scalaTestVersion % Test + ("com.typesafe.akka" %% "akka-actor" % akkaVersion % Provided).cross(CrossVersion.for3Use2_13), + ("com.typesafe.akka" %% "akka-stream" % akkaVersion % Provided).cross(CrossVersion.for3Use2_13), + ("com.typesafe.akka" %% "akka-http" % akkaHttpVersion % Provided).cross(CrossVersion.for3Use2_13), + ("com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion % Provided).cross(CrossVersion.for3Use2_13), + "io.prometheus" % "simpleclient" % simpleclientVersion, + "io.prometheus" % "simpleclient_common" % simpleclientVersion, + ("com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test).cross(CrossVersion.for3Use2_13), + ("com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion % Test).cross(CrossVersion.for3Use2_13), + "org.scalatest" %% "scalatest" % scalaTestVersion % Test ) } diff --git a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala index 6a3d1e4..247427b 100644 --- a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala +++ b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala @@ -2,7 +2,6 @@ package com.varwise.akka.http.prometheus import com.varwise.akka.http.prometheus.Utils._ import io.prometheus.client.{Collector, CollectorRegistry} -import org.scalamock.scalatest.MockFactory import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers @@ -10,7 +9,7 @@ import scala.concurrent.duration import scala.concurrent.duration.FiniteDuration import scala.util.Random -class PrometheusResponseTimeRecorderSpec extends AnyFlatSpec with Matchers with MockFactory { +class PrometheusResponseTimeRecorderSpec extends AnyFlatSpec with Matchers { "PrometheusLatencyRecorder" should "register a histogram and record request latencies" in { val registry = new CollectorRegistry() From 98844f6405073514b2e2be71bf4c2adf1533d190 Mon Sep 17 00:00:00 2001 From: Wojciech Langiewicz Date: Wed, 6 Oct 2021 13:00:49 +0200 Subject: [PATCH 3/3] reorder functions, add explicit return types --- .../akka/http/prometheus/EventObserver.scala | 2 +- .../prometheus/ResponseTimeRecorder.scala | 2 +- .../PrometheusResponseTimeRecorderSpec.scala | 31 +++++++++---------- .../prometheus/api/MetricsEndpointSpec.scala | 12 +++---- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/main/scala/com/varwise/akka/http/prometheus/EventObserver.scala b/src/main/scala/com/varwise/akka/http/prometheus/EventObserver.scala index 75c1122..0976fe7 100644 --- a/src/main/scala/com/varwise/akka/http/prometheus/EventObserver.scala +++ b/src/main/scala/com/varwise/akka/http/prometheus/EventObserver.scala @@ -25,7 +25,7 @@ class PrometheusEventObserver( val counter: Counter = buildCounter.register(registry) - private def buildCounter = + private def buildCounter: Counter.Builder = Counter .build() .name(metricName) diff --git a/src/main/scala/com/varwise/akka/http/prometheus/ResponseTimeRecorder.scala b/src/main/scala/com/varwise/akka/http/prometheus/ResponseTimeRecorder.scala index fe10e16..768c7d2 100644 --- a/src/main/scala/com/varwise/akka/http/prometheus/ResponseTimeRecorder.scala +++ b/src/main/scala/com/varwise/akka/http/prometheus/ResponseTimeRecorder.scala @@ -34,7 +34,7 @@ class PrometheusResponseTimeRecorder( override def recordResponseTime(endpoint: String, responseTime: FiniteDuration): Unit = responseTimes.labels(endpoint).observe(responseTime.toUnit(timeUnit)) - private def buildHistogram = + private def buildHistogram: Histogram.Builder = Histogram .build() .name(metricName) diff --git a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala index 247427b..094ddf8 100644 --- a/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala +++ b/src/test/scala/com/varwise/akka/http/prometheus/PrometheusResponseTimeRecorderSpec.scala @@ -11,6 +11,21 @@ import scala.util.Random class PrometheusResponseTimeRecorderSpec extends AnyFlatSpec with Matchers { + private def getBucketValue( + registry: CollectorRegistry, + metricName: String, + labelNames: List[String], + labelValues: List[String], + bucket: Double + ): Int = { + val name = metricName + "_bucket" + + // 'le' should be the first label in the list + val allLabelNames = (Array("le") ++ labelNames).reverse + val allLabelValues = (Array(Collector.doubleToGoString(bucket)) ++ labelValues).reverse + registry.getSampleValue(name, allLabelNames, allLabelValues).intValue() + } + "PrometheusLatencyRecorder" should "register a histogram and record request latencies" in { val registry = new CollectorRegistry() val randomMetricName = generateRandomString @@ -49,20 +64,4 @@ class PrometheusResponseTimeRecorderSpec extends AnyFlatSpec with Matchers { second shouldBe 1 positiveInf shouldBe 1 } - - private def getBucketValue( - registry: CollectorRegistry, - metricName: String, - labelNames: List[String], - labelValues: List[String], - bucket: Double - ): Int = { - val name = metricName + "_bucket" - - // 'le' should be the first label in the list - val allLabelNames = (Array("le") ++ labelNames).reverse - val allLabelValues = (Array(Collector.doubleToGoString(bucket)) ++ labelValues).reverse - registry.getSampleValue(name, allLabelNames, allLabelValues).intValue() - } - } diff --git a/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala b/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala index c77edbe..1ea0332 100644 --- a/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala +++ b/src/test/scala/com/varwise/akka/http/prometheus/api/MetricsEndpointSpec.scala @@ -13,6 +13,9 @@ import scala.util.Random class MetricsEndpointSpec extends AnyFlatSpec with Matchers with ScalatestRouteTest { + private def createEndpoint(collectorRegistry: CollectorRegistry) = + new MetricsEndpoint(collectorRegistry) + "Metrics endpoint" should "return the correct media type and charset" in { val api = createEndpoint(CollectorRegistry.defaultRegistry) Get("/metrics") ~> api.routes ~> check { @@ -26,6 +29,8 @@ class MetricsEndpointSpec extends AnyFlatSpec with Matchers with ScalatestRouteT it should "return serialized metrics in the prometheus text format" in { val registry = new CollectorRegistry() val api = createEndpoint(registry) + val RandomTestName = generateRandomStringOfLength(16) + val RandomTestHelp = generateRandomStringOfLength(16) val hist = Histogram.build().name(RandomTestName).help(RandomTestHelp).linearBuckets(0, 1, 10).register(registry) hist.observe(Math.abs(Random.nextDouble())) @@ -38,11 +43,4 @@ class MetricsEndpointSpec extends AnyFlatSpec with Matchers with ScalatestRouteT resp shouldBe writer.toString } } - - private val RandomTestName = generateRandomStringOfLength(16) - private val RandomTestHelp = generateRandomStringOfLength(16) - - private def createEndpoint(collectorRegistry: CollectorRegistry) = - new MetricsEndpoint(collectorRegistry) - }