From 35e926b9c6168f3e34670b2ec01b4cf900546c20 Mon Sep 17 00:00:00 2001 From: Maksim Ochenashko Date: Wed, 3 Aug 2022 14:01:28 +0300 Subject: [PATCH 1/3] Split project into modules --- .github/workflows/ci.yml | 4 +- build.sbt | 131 +++++++--- .../scala/org/typelevel/otel4s/Otel4s.scala | 2 +- .../org/typelevel/otel4s/Attribute.scala | 0 .../org/typelevel/otel4s/AttributeKey.scala | 0 .../org/typelevel/otel4s/AttributeType.scala | 0 .../otel4s/meta/InstrumentMeta.scala | 47 ++++ .../otel4s/meta/InstrumentMetaSuite.scala} | 25 +- .../otel4s/metrics/CounterMacro.scala | 31 ++- .../otel4s/metrics/HistogramMacro.scala | 31 ++- .../otel4s/metrics/UpDownCounterMacro.scala | 42 +++- .../otel4s/metrics/CounterMacro.scala | 28 ++- .../otel4s/metrics/HistogramMacro.scala | 30 ++- .../otel4s/metrics/UpDownCounterMacro.scala | 39 ++- .../typelevel/otel4s/metrics/Counter.scala | 19 +- .../typelevel/otel4s/metrics/Histogram.scala | 29 ++- .../org/typelevel/otel4s/metrics/Meter.scala | 0 .../otel4s/metrics/MeterBuilder.scala | 0 .../otel4s/metrics/MeterProvider.scala | 0 .../otel4s/metrics/ObservableCounter.scala | 0 .../otel4s/metrics/ObservableGauge.scala | 0 .../metrics/ObservableInstrumentBuilder.scala | 0 .../metrics/ObservableUpDownCounter.scala | 0 .../metrics/SyncInstrumentBuilder.scala | 0 .../otel4s/metrics/UpDownCounter.scala | 21 +- .../otel4s/metrics/CounterSuite.scala | 3 +- .../otel4s/metrics/HistogramSuite.scala | 2 +- .../otel4s/metrics/UpDownCounterSuite.scala | 3 +- .../otel4s/metrics/MetricsMacro.scala | 73 ------ .../otel4s/metrics/MetricsMacro.scala | 95 -------- .../org/typelevel/otel4s/java/OtelJava.scala | 33 +++ .../typelevel/otel4s/java/Conversions.scala | 74 ++++++ .../org/typelevel/otel4s/java/Metrics.scala | 35 +++ .../java/metrics/CounterBuilderImpl.scala | 45 ++++ .../otel4s/java/metrics/CounterImpl.scala | 39 +++ .../java/metrics/HistogramBuilderImpl.scala | 45 ++++ .../otel4s/java/metrics/HistogramImpl.scala | 39 +++ .../java/metrics/MeterBuilderImpl.scala | 44 ++++ .../otel4s/java/metrics/MeterImpl.scala | 38 +++ .../java/metrics/MeterProviderImpl.scala | 32 +++ .../metrics/UpDownCounterBuilderImpl.scala | 46 ++++ .../java/metrics/UpDownCounterImpl.scala | 39 +++ .../otel4s/java/metrics/CounterSuite.scala} | 15 +- .../org/typelevel/otel4s/java/impl.scala | 226 ------------------ java/src/test/scala/com/example/PoC.scala | 63 ----- .../typelevel/otel4s/testkit/Implicits.scala | 0 .../testkit/InstrumentationResource.scala} | 20 +- .../otel4s/testkit/InstrumentationScope.scala | 0 .../otel4s/testkit/metrics/MetricsSdk.scala} | 11 +- .../testkit/metrics}/HistogramPointData.scala | 2 +- .../otel4s/testkit/metrics}/Metric.scala | 3 +- .../otel4s/testkit/metrics}/MetricData.scala | 2 +- .../otel4s/testkit/metrics}/PointData.scala | 1 + .../testkit/metrics}/QuantileData.scala | 2 +- .../testkit/metrics}/SummaryPointData.scala | 2 +- 55 files changed, 945 insertions(+), 566 deletions(-) rename core/{ => all}/src/main/scala/org/typelevel/otel4s/Otel4s.scala (90%) rename core/{ => common}/src/main/scala/org/typelevel/otel4s/Attribute.scala (100%) rename core/{ => common}/src/main/scala/org/typelevel/otel4s/AttributeKey.scala (100%) rename core/{ => common}/src/main/scala/org/typelevel/otel4s/AttributeType.scala (100%) create mode 100644 core/common/src/main/scala/org/typelevel/otel4s/meta/InstrumentMeta.scala rename core/{src/main/scala/org/typelevel/otel4s/metrics/InstrumentBackend.scala => common/src/test/scala/org/typelevel/otel4s/meta/InstrumentMetaSuite.scala} (58%) rename core/{ => metrics}/src/main/scala-2/org/typelevel/otel4s/metrics/CounterMacro.scala (63%) rename core/{ => metrics}/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala (68%) rename core/{ => metrics}/src/main/scala-2/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala (57%) rename core/{ => metrics}/src/main/scala-3/org/typelevel/otel4s/metrics/CounterMacro.scala (65%) rename core/{ => metrics}/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala (69%) rename core/{ => metrics}/src/main/scala-3/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala (58%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/Counter.scala (82%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala (84%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/Meter.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/MeterBuilder.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/MeterProvider.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/ObservableCounter.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/ObservableGauge.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/ObservableInstrumentBuilder.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/ObservableUpDownCounter.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/SyncInstrumentBuilder.scala (100%) rename core/{ => metrics}/src/main/scala/org/typelevel/otel4s/metrics/UpDownCounter.scala (83%) rename core/{ => metrics}/src/test/scala/org/typelevel/otel4s/metrics/CounterSuite.scala (96%) rename core/{ => metrics}/src/test/scala/org/typelevel/otel4s/metrics/HistogramSuite.scala (98%) rename core/{ => metrics}/src/test/scala/org/typelevel/otel4s/metrics/UpDownCounterSuite.scala (96%) delete mode 100644 core/src/main/scala-2/org/typelevel/otel4s/metrics/MetricsMacro.scala delete mode 100644 core/src/main/scala-3/org/typelevel/otel4s/metrics/MetricsMacro.scala create mode 100644 java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala create mode 100644 java/common/src/main/scala/org/typelevel/otel4s/java/Conversions.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala create mode 100644 java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala rename java/{src/test/scala/org/typelevel/otel4s/java/JavaOtelSuite.scala => metrics/src/test/scala/org/typelevel/otel4s/java/metrics/CounterSuite.scala} (89%) delete mode 100644 java/src/main/scala/org/typelevel/otel4s/java/impl.scala delete mode 100644 java/src/test/scala/com/example/PoC.scala rename testkit/{ => common}/shared/src/main/scala/org/typelevel/otel4s/testkit/Implicits.scala (100%) rename testkit/{shared/src/main/scala/org/typelevel/otel4s/testkit/MetricResource.scala => common/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationResource.scala} (67%) rename testkit/{ => common}/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationScope.scala (100%) rename testkit/{jvm/src/main/scala/org/typelevel/otel4s/testkit/Sdk.scala => metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala} (97%) rename testkit/{shared/src/main/scala/org/typelevel/otel4s/testkit => metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics}/HistogramPointData.scala (97%) rename testkit/{shared/src/main/scala/org/typelevel/otel4s/testkit => metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics}/Metric.scala (96%) rename testkit/{shared/src/main/scala/org/typelevel/otel4s/testkit => metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics}/MetricData.scala (98%) rename testkit/{shared/src/main/scala/org/typelevel/otel4s/testkit => metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics}/PointData.scala (98%) rename testkit/{shared/src/main/scala/org/typelevel/otel4s/testkit => metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics}/QuantileData.scala (96%) rename testkit/{shared/src/main/scala/org/typelevel/otel4s/testkit => metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics}/SummaryPointData.scala (96%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f05852f47..2a26a224f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,11 +94,11 @@ jobs: - name: Make target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: mkdir -p target .js/target site/target core/.js/target core/.jvm/target .jvm/target .native/target java/.jvm/target testkit/jvm/target project/target + run: mkdir -p testkit/metrics/jvm/target testkit/common/jvm/target target java/common/.jvm/target core/common/.jvm/target .js/target site/target core/metrics/.jvm/target java/metrics/.jvm/target core/all/.js/target core/metrics/.js/target core/all/.jvm/target .jvm/target .native/target core/common/.js/target java/all/.jvm/target testkit/all/jvm/target project/target - name: Compress target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: tar cf targets.tar target .js/target site/target core/.js/target core/.jvm/target .jvm/target .native/target java/.jvm/target testkit/jvm/target project/target + run: tar cf targets.tar testkit/metrics/jvm/target testkit/common/jvm/target target java/common/.jvm/target core/common/.jvm/target .js/target site/target core/metrics/.jvm/target java/metrics/.jvm/target core/all/.js/target core/metrics/.js/target core/all/.jvm/target .jvm/target .native/target core/common/.js/target java/all/.jvm/target testkit/all/jvm/target project/target - name: Upload target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') diff --git a/build.sbt b/build.sbt index aa502b320..1f04f66c1 100644 --- a/build.sbt +++ b/build.sbt @@ -21,57 +21,130 @@ val Scala213 = "2.13.8" ThisBuild / crossScalaVersions := Seq(Scala213, "3.1.3") ThisBuild / scalaVersion := Scala213 // the default Scala +val CatsVersion = "2.8.0" +val CatsEffectVersion = "3.3.13" +val MUnitVersion = "0.7.29" +val MUnitCatsEffectVersion = "1.0.7" +val OpenTelemetryVersion = "1.15.0" + +lazy val scalaReflectDependency = Def.settings( + libraryDependencies ++= { + if (tlIsScala3.value) Nil + else Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided) + } +) + lazy val root = tlCrossRootProject - .aggregate(core, testkit, java) + .aggregate( + `core-common`, + `core-metrics`, + core, + `testkit-common`, + `testkit-metrics`, + testkit, + `java-common`, + `java-metrics`, + java + ) .settings(name := "otel4s") +lazy val `core-common` = crossProject(JVMPlatform, JSPlatform) + .crossType(CrossType.Pure) + .in(file("core/common")) + .settings( + name := "otel4s-core-common", + libraryDependencies ++= Seq( + "org.typelevel" %%% "cats-core" % CatsVersion, + "org.scalameta" %%% "munit" % MUnitVersion % Test + ) + ) + +lazy val `core-metrics` = crossProject(JVMPlatform, JSPlatform) + .crossType(CrossType.Pure) + .in(file("core/metrics")) + .dependsOn(`core-common`) + .settings(scalaReflectDependency) + .settings( + name := "otel4s-core-metrics", + libraryDependencies ++= Seq( + "org.typelevel" %%% "cats-effect" % CatsEffectVersion, + "org.scalameta" %%% "munit" % MUnitVersion % Test, + "org.typelevel" %%% "munit-cats-effect-3" % MUnitCatsEffectVersion % Test, + "org.typelevel" %%% "cats-effect-testkit" % CatsEffectVersion % Test + ) + ) + lazy val core = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Pure) - .in(file("core")) + .in(file("core/all")) + .dependsOn(`core-common`, `core-metrics`) .settings( - name := "otel4s-core", + name := "otel4s-core" + ) + +lazy val `testkit-common` = crossProject(JVMPlatform) + .crossType(CrossType.Full) + .in(file("testkit/common")) + .dependsOn(`core-common`) + .settings( + name := "otel4s-testkit-common" + ) + +lazy val `testkit-metrics` = crossProject(JVMPlatform) + .crossType(CrossType.Full) + .in(file("testkit/metrics")) + .dependsOn(`testkit-common`, `core-metrics`) + .settings( + name := "otel4s-testkit-metrics" + ) + .jvmSettings( libraryDependencies ++= Seq( - "org.typelevel" %%% "cats-core" % "2.8.0", - "org.typelevel" %%% "cats-effect" % "3.3.13", - "org.scalameta" %%% "munit" % "0.7.29" % Test, - "org.typelevel" %%% "munit-cats-effect-3" % "1.0.7" % Test, - "org.typelevel" %%% "cats-effect-testkit" % "3.3.13" % Test - ), - libraryDependencies ++= { - if (tlIsScala3.value) Nil - else - Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided) - } + "io.opentelemetry" % "opentelemetry-api" % OpenTelemetryVersion, + "io.opentelemetry" % "opentelemetry-sdk" % OpenTelemetryVersion, + "io.opentelemetry" % "opentelemetry-sdk-testing" % OpenTelemetryVersion + ) ) lazy val testkit = crossProject(JVMPlatform) .crossType(CrossType.Full) - .in(file("testkit")) + .in(file("testkit/all")) + .dependsOn(`testkit-common`, `testkit-metrics`) .settings( name := "otel4s-testkit" ) - .jvmSettings( + +lazy val `java-common` = crossProject(JVMPlatform) + .crossType(CrossType.Pure) + .in(file("java/common")) + .dependsOn(`core-common`, `testkit-common`) + .settings( + name := "otel4s-java-common", libraryDependencies ++= Seq( - "io.opentelemetry" % "opentelemetry-api" % "1.15.0", - "io.opentelemetry" % "opentelemetry-sdk" % "1.15.0", - "io.opentelemetry" % "opentelemetry-sdk-testing" % "1.15.0" + "io.opentelemetry" % "opentelemetry-api" % OpenTelemetryVersion ) ) - .dependsOn(core) -lazy val java = crossProject(JVMPlatform) +lazy val `java-metrics` = crossProject(JVMPlatform) .crossType(CrossType.Pure) - .in(file("java")) + .in(file("java/metrics")) + .dependsOn(`java-common`, `core-metrics`, `testkit-metrics`) .settings( - name := "otel4s-java", + name := "otel4s-java-metrics", libraryDependencies ++= Seq( - "io.opentelemetry" % "opentelemetry-api" % "1.15.0", - "io.opentelemetry" % "opentelemetry-sdk" % "1.15.0" % Test, - "io.opentelemetry" % "opentelemetry-sdk-testing" % "1.15.0" % Test, - "org.scalameta" %% "munit" % "0.7.29" % Test, - "org.typelevel" %% "munit-cats-effect-3" % "1.0.7" % Test + "io.opentelemetry" % "opentelemetry-api" % OpenTelemetryVersion, + "io.opentelemetry" % "opentelemetry-sdk" % OpenTelemetryVersion % Test, + "io.opentelemetry" % "opentelemetry-sdk-testing" % OpenTelemetryVersion % Test, + "org.scalameta" %% "munit" % MUnitVersion % Test, + "org.typelevel" %% "munit-cats-effect-3" % MUnitCatsEffectVersion % Test ) ) - .dependsOn(core, testkit) + +lazy val java = crossProject(JVMPlatform) + .crossType(CrossType.Pure) + .in(file("java/all")) + .dependsOn(core, `java-metrics`) + .settings( + name := "otel4s-java" + ) lazy val docs = project.in(file("site")).enablePlugins(TypelevelSitePlugin) diff --git a/core/src/main/scala/org/typelevel/otel4s/Otel4s.scala b/core/all/src/main/scala/org/typelevel/otel4s/Otel4s.scala similarity index 90% rename from core/src/main/scala/org/typelevel/otel4s/Otel4s.scala rename to core/all/src/main/scala/org/typelevel/otel4s/Otel4s.scala index 3d1a14beb..0a5c8a069 100644 --- a/core/src/main/scala/org/typelevel/otel4s/Otel4s.scala +++ b/core/all/src/main/scala/org/typelevel/otel4s/Otel4s.scala @@ -20,7 +20,7 @@ import org.typelevel.otel4s.metrics.MeterProvider trait Otel4s[F[_]] { - /** A registry for creating named [[org.typelevel.otel4s.metrics.Meter]]. + /** A registry for creating named meters. */ def meterProvider: MeterProvider[F] } diff --git a/core/src/main/scala/org/typelevel/otel4s/Attribute.scala b/core/common/src/main/scala/org/typelevel/otel4s/Attribute.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/Attribute.scala rename to core/common/src/main/scala/org/typelevel/otel4s/Attribute.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/AttributeKey.scala b/core/common/src/main/scala/org/typelevel/otel4s/AttributeKey.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/AttributeKey.scala rename to core/common/src/main/scala/org/typelevel/otel4s/AttributeKey.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/AttributeType.scala b/core/common/src/main/scala/org/typelevel/otel4s/AttributeType.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/AttributeType.scala rename to core/common/src/main/scala/org/typelevel/otel4s/AttributeType.scala diff --git a/core/common/src/main/scala/org/typelevel/otel4s/meta/InstrumentMeta.scala b/core/common/src/main/scala/org/typelevel/otel4s/meta/InstrumentMeta.scala new file mode 100644 index 000000000..946d13076 --- /dev/null +++ b/core/common/src/main/scala/org/typelevel/otel4s/meta/InstrumentMeta.scala @@ -0,0 +1,47 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s.meta + +import cats.Applicative + +trait InstrumentMeta[F[_]] { + + /** Indicates whether instrumentation is enabled or not. + */ + def isEnabled: Boolean + + /** A no-op effect. + */ + def unit: F[Unit] + +} + +object InstrumentMeta { + + def enabled[F[_]: Applicative]: InstrumentMeta[F] = + make(enabled = true) + + def disabled[F[_]: Applicative]: InstrumentMeta[F] = + make(enabled = false) + + private def make[F[_]: Applicative](enabled: Boolean): InstrumentMeta[F] = + new InstrumentMeta[F] { + val isEnabled: Boolean = enabled + val unit: F[Unit] = Applicative[F].unit + } + +} diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/InstrumentBackend.scala b/core/common/src/test/scala/org/typelevel/otel4s/meta/InstrumentMetaSuite.scala similarity index 58% rename from core/src/main/scala/org/typelevel/otel4s/metrics/InstrumentBackend.scala rename to core/common/src/test/scala/org/typelevel/otel4s/meta/InstrumentMetaSuite.scala index 4a5c35a6b..38766f157 100644 --- a/core/src/main/scala/org/typelevel/otel4s/metrics/InstrumentBackend.scala +++ b/core/common/src/test/scala/org/typelevel/otel4s/meta/InstrumentMetaSuite.scala @@ -14,11 +14,24 @@ * limitations under the License. */ -package org.typelevel.otel4s.metrics +package org.typelevel.otel4s.meta + +import munit.FunSuite + +class InstrumentMetaSuite extends FunSuite { + + test("enabled") { + val disabled = InstrumentMeta.enabled[cats.Id] + + assertEquals(disabled.unit, ()) + assertEquals(disabled.isEnabled, true) + } + + test("disabled") { + val disabled = InstrumentMeta.disabled[cats.Id] + + assertEquals(disabled.unit, ()) + assertEquals(disabled.isEnabled, false) + } -/** A backend that implements instrument operations: add, record, etc. - */ -trait InstrumentBackend[F[_]] { - def isEnabled: Boolean - def unit: F[Unit] } diff --git a/core/src/main/scala-2/org/typelevel/otel4s/metrics/CounterMacro.scala b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/CounterMacro.scala similarity index 63% rename from core/src/main/scala-2/org/typelevel/otel4s/metrics/CounterMacro.scala rename to core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/CounterMacro.scala index 7c80f00db..821c6340e 100644 --- a/core/src/main/scala-2/org/typelevel/otel4s/metrics/CounterMacro.scala +++ b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/CounterMacro.scala @@ -29,7 +29,7 @@ private[otel4s] trait CounterMacro[F[_], A] { * the set of attributes to associate with the value */ def add(value: A, attributes: Attribute[_]*): F[Unit] = - macro MetricsMacro.add[A] + macro CounterMacro.add[A] /** Increments a counter by one. * @@ -37,5 +37,32 @@ private[otel4s] trait CounterMacro[F[_], A] { * the set of attributes to associate with the value */ def inc(attributes: Attribute[_]*): F[Unit] = - macro MetricsMacro.inc + macro CounterMacro.inc + +} + +object CounterMacro { + import scala.reflect.macros.blackbox + + def add[A](c: blackbox.Context)( + value: c.Expr[A], + attributes: c.Expr[Attribute[_]]* + ): c.universe.Tree = { + import c.universe._ + val backend = q"${c.prefix}.backend" + val meta = q"$backend.meta" + + q"if ($meta.isEnabled) $backend.add($value, ..$attributes) else $meta.unit" + } + + def inc(c: blackbox.Context)( + attributes: c.Expr[Attribute[_]]* + ): c.universe.Tree = { + import c.universe._ + val backend = q"${c.prefix}.backend" + val meta = q"$backend.meta" + + q"if ($meta.isEnabled) $backend.inc(..$attributes) else $meta.unit" + } + } diff --git a/core/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala similarity index 68% rename from core/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala rename to core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala index f0d731821..e40346866 100644 --- a/core/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala +++ b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala @@ -33,7 +33,7 @@ private[otel4s] trait HistogramMacro[F[_], A] { * the set of attributes to associate with the value */ def record(value: A, attributes: Attribute[_]*): F[Unit] = - macro MetricsMacro.record[A] + macro HistogramMacro.record[A] /** Records duration of the given effect. * @@ -58,6 +58,33 @@ private[otel4s] trait HistogramMacro[F[_], A] { timeUnit: TimeUnit, attributes: Attribute[_]* ): Resource[F, Unit] = - macro MetricsMacro.recordDuration + macro HistogramMacro.recordDuration + +} + +object HistogramMacro { + import scala.reflect.macros.blackbox + + def record[A](c: blackbox.Context)( + value: c.Expr[A], + attributes: c.Expr[Attribute[_]]* + ): c.universe.Tree = { + import c.universe._ + val backend = q"${c.prefix}.backend" + val meta = q"$backend.meta" + + q"if ($meta.isEnabled) $backend.record($value, ..$attributes) else $meta.unit" + } + + def recordDuration(c: blackbox.Context)( + timeUnit: c.Expr[TimeUnit], + attributes: c.Expr[Attribute[_]]* + ): c.universe.Tree = { + import c.universe._ + val backend = q"${c.prefix}.backend" + val meta = q"$backend.meta" + + q"if ($meta.isEnabled) $backend.recordDuration($timeUnit, ..$attributes) else $meta.resourceUnit" + } } diff --git a/core/src/main/scala-2/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala similarity index 57% rename from core/src/main/scala-2/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala rename to core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala index e8335b6f3..2879f4cfe 100644 --- a/core/src/main/scala-2/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala +++ b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala @@ -29,7 +29,7 @@ private[otel4s] trait UpDownCounterMacro[F[_], A] { * the set of attributes to associate with the value */ def add(value: A, attributes: Attribute[_]*): F[Unit] = - macro MetricsMacro.add[A] + macro UpDownCounterMacro.add[A] /** Increments a counter by one. * @@ -37,7 +37,7 @@ private[otel4s] trait UpDownCounterMacro[F[_], A] { * the set of attributes to associate with the value */ def inc(attributes: Attribute[_]*): F[Unit] = - macro MetricsMacro.inc + macro UpDownCounterMacro.inc /** Decrements a counter by one. * @@ -45,6 +45,42 @@ private[otel4s] trait UpDownCounterMacro[F[_], A] { * the set of attributes to associate with the value */ def dec(attributes: Attribute[_]*): F[Unit] = - macro MetricsMacro.dec + macro UpDownCounterMacro.dec + +} + +object UpDownCounterMacro { + import scala.reflect.macros.blackbox + + def add[A](c: blackbox.Context)( + value: c.Expr[A], + attributes: c.Expr[Attribute[_]]* + ): c.universe.Tree = { + import c.universe._ + val backend = q"${c.prefix}.backend" + val meta = q"$backend.meta" + + q"if ($meta.isEnabled) $backend.add($value, ..$attributes) else $meta.unit" + } + + def inc(c: blackbox.Context)( + attributes: c.Expr[Attribute[_]]* + ): c.universe.Tree = { + import c.universe._ + val backend = q"${c.prefix}.backend" + val meta = q"$backend.meta" + + q"if ($meta.isEnabled) $backend.inc(..$attributes) else $meta.unit" + } + + def dec(c: blackbox.Context)( + attributes: c.Expr[Attribute[_]]* + ): c.universe.Tree = { + import c.universe._ + val backend = q"${c.prefix}.backend" + val meta = q"$backend.meta" + + q"if ($meta.isEnabled) $backend.dec(..$attributes) else $meta.unit" + } } diff --git a/core/src/main/scala-3/org/typelevel/otel4s/metrics/CounterMacro.scala b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/CounterMacro.scala similarity index 65% rename from core/src/main/scala-3/org/typelevel/otel4s/metrics/CounterMacro.scala rename to core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/CounterMacro.scala index 8bb2c6c88..a1857eccd 100644 --- a/core/src/main/scala-3/org/typelevel/otel4s/metrics/CounterMacro.scala +++ b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/CounterMacro.scala @@ -31,7 +31,7 @@ private[otel4s] trait CounterMacro[F[_], A] { * the set of attributes to associate with the value */ inline def add(inline value: A, inline attributes: Attribute[_]*): F[Unit] = - ${ MetricsMacro.counter.add('backend, 'value, 'attributes) } + ${ CounterMacro.add('backend, 'value, 'attributes) } /** Increments a counter by one. * @@ -39,5 +39,29 @@ private[otel4s] trait CounterMacro[F[_], A] { * the set of attributes to associate with the value */ inline def inc(inline attributes: Attribute[_]*): F[Unit] = - ${ MetricsMacro.counter.inc('backend, 'attributes) } + ${ CounterMacro.inc('backend, 'attributes) } + +} + +object CounterMacro { + + def add[F[_], A]( + backend: Expr[Counter.Backend[F, A]], + value: Expr[A], + attributes: Expr[Seq[Attribute[_]]] + )(using Quotes, Type[F], Type[A]) = + '{ + if ($backend.meta.isEnabled) $backend.add($value, $attributes*) + else $backend.meta.unit + } + + def inc[F[_], A]( + backend: Expr[Counter.Backend[F, A]], + attributes: Expr[Seq[Attribute[_]]] + )(using Quotes, Type[F], Type[A]) = + '{ + if ($backend.meta.isEnabled) $backend.inc($attributes*) + else $backend.meta.unit + } + } diff --git a/core/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala similarity index 69% rename from core/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala rename to core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala index 52e363a03..ad964d627 100644 --- a/core/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala +++ b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala @@ -37,7 +37,7 @@ private[otel4s] trait HistogramMacro[F[_], A] { inline value: A, inline attributes: Attribute[_]* ): F[Unit] = - ${ MetricsMacro.histogram.record('backend, 'value, 'attributes) } + ${ HistogramMacro.record('backend, 'value, 'attributes) } /** Records duration of the given effect. * @@ -62,5 +62,31 @@ private[otel4s] trait HistogramMacro[F[_], A] { inline timeUnit: TimeUnit, inline attributes: Attribute[_]* ): Resource[F, Unit] = - ${ MetricsMacro.histogram.recordDuration('backend, 'timeUnit, 'attributes) } + ${ HistogramMacro.recordDuration('backend, 'timeUnit, 'attributes) } + +} + +object HistogramMacro { + + def record[F[_], A]( + backend: Expr[Histogram.Backend[F, A]], + value: Expr[A], + attributes: Expr[Seq[Attribute[_]]] + )(using Quotes, Type[F], Type[A]) = + '{ + if ($backend.meta.isEnabled) $backend.record($value, $attributes*) + else $backend.meta.unit + } + + def recordDuration[F[_], A]( + backend: Expr[Histogram.Backend[F, A]], + timeUnit: Expr[TimeUnit], + attributes: Expr[Seq[Attribute[_]]] + )(using Quotes, Type[F], Type[A]) = + '{ + if ($backend.meta.isEnabled) + $backend.recordDuration($timeUnit, $attributes*) + else $backend.meta.resourceUnit + } + } diff --git a/core/src/main/scala-3/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala similarity index 58% rename from core/src/main/scala-3/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala rename to core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala index a20db17fe..b50b8260d 100644 --- a/core/src/main/scala-3/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala +++ b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/UpDownCounterMacro.scala @@ -31,7 +31,7 @@ private[otel4s] trait UpDownCounterMacro[F[_], A] { * the set of attributes to associate with the value */ inline def add(inline value: A, inline attributes: Attribute[_]*): F[Unit] = - ${ MetricsMacro.upDownCounter.add('backend, 'value, 'attributes) } + ${ UpDownCounterMacro.add('backend, 'value, 'attributes) } /** Increments a counter by one. * @@ -39,7 +39,7 @@ private[otel4s] trait UpDownCounterMacro[F[_], A] { * the set of attributes to associate with the value */ inline def inc(inline attributes: Attribute[_]*): F[Unit] = - ${ MetricsMacro.upDownCounter.inc('backend, 'attributes) } + ${ UpDownCounterMacro.inc('backend, 'attributes) } /** Decrements a counter by one. * @@ -47,5 +47,38 @@ private[otel4s] trait UpDownCounterMacro[F[_], A] { * the set of attributes to associate with the value */ inline def dec(inline attributes: Attribute[_]*): F[Unit] = - ${ MetricsMacro.upDownCounter.dec('backend, 'attributes) } + ${ UpDownCounterMacro.dec('backend, 'attributes) } + +} + +object UpDownCounterMacro { + + def add[F[_], A]( + backend: Expr[UpDownCounter.Backend[F, A]], + value: Expr[A], + attributes: Expr[Seq[Attribute[_]]] + )(using Quotes, Type[F], Type[A]) = + '{ + if ($backend.meta.isEnabled) $backend.add($value, $attributes*) + else $backend.meta.unit + } + + def inc[F[_], A]( + backend: Expr[UpDownCounter.Backend[F, A]], + attributes: Expr[Seq[Attribute[_]]] + )(using Quotes, Type[F], Type[A]) = + '{ + if ($backend.meta.isEnabled) $backend.inc($attributes*) + else $backend.meta.unit + } + + def dec[F[_], A]( + backend: Expr[UpDownCounter.Backend[F, A]], + attributes: Expr[Seq[Attribute[_]]] + )(using Quotes, Type[F], Type[A]) = + '{ + if ($backend.meta.isEnabled) $backend.dec($attributes*) + else $backend.meta.unit + } + } diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/Counter.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Counter.scala similarity index 82% rename from core/src/main/scala/org/typelevel/otel4s/metrics/Counter.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Counter.scala index 9c2b11965..fd0f82b78 100644 --- a/core/src/main/scala/org/typelevel/otel4s/metrics/Counter.scala +++ b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Counter.scala @@ -18,6 +18,7 @@ package org.typelevel.otel4s package metrics import cats.Applicative +import org.typelevel.otel4s.meta.InstrumentMeta /** A `Counter` instrument that records values of type `A`. * @@ -37,7 +38,8 @@ trait Counter[F[_], A] extends CounterMacro[F, A] object Counter { - trait Backend[F[_], A] extends InstrumentBackend[F] { + trait Backend[F[_], A] { + def meta: InstrumentMeta[F] /** Records a value with a set of attributes. * @@ -57,16 +59,12 @@ object Counter { def inc(attributes: Attribute[_]*): F[Unit] } - abstract class LongBackend[F[_]: Applicative] extends Backend[F, Long] { - final val unit: F[Unit] = Applicative[F].unit - + trait LongBackend[F[_]] extends Backend[F, Long] { final def inc(attributes: Attribute[_]*): F[Unit] = add(1L, attributes: _*) } - abstract class DoubleBackend[F[_]: Applicative] extends Backend[F, Double] { - final val unit: F[Unit] = Applicative[F].unit - + trait DoubleBackend[F[_]] extends Backend[F, Double] { final def inc(attributes: Attribute[_]*): F[Unit] = add(1.0, attributes: _*) } @@ -75,10 +73,9 @@ object Counter { new Counter[F, A] { val backend: Backend[F, A] = new Backend[F, A] { - val isEnabled: Boolean = false - val unit: F[Unit] = F.unit - def add(value: A, attributes: Attribute[_]*): F[Unit] = unit - def inc(attributes: Attribute[_]*): F[Unit] = unit + val meta: InstrumentMeta[F] = InstrumentMeta.disabled + def add(value: A, attributes: Attribute[_]*): F[Unit] = meta.unit + def inc(attributes: Attribute[_]*): F[Unit] = meta.unit } } diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala similarity index 84% rename from core/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala index fbdd9ff65..ec7e97bfa 100644 --- a/core/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala +++ b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala @@ -23,6 +23,7 @@ import cats.effect.Clock import cats.effect.Resource import cats.syntax.flatMap._ import cats.syntax.functor._ +import org.typelevel.otel4s.meta.InstrumentMeta import scala.concurrent.duration.TimeUnit @@ -35,6 +36,7 @@ import scala.concurrent.duration.TimeUnit * * @tparam F * the higher-kinded type of a polymorphic effect + * * @tparam A * the type of the values to record. OpenTelemetry specification expects `A` * to be either [[scala.Long]] or [[scala.Double]]. @@ -43,8 +45,24 @@ trait Histogram[F[_], A] extends HistogramMacro[F, A] object Histogram { - trait Backend[F[_], A] extends InstrumentBackend[F] { - final val resourceUnit: Resource[F, Unit] = Resource.unit + trait Meta[F[_]] extends InstrumentMeta[F] { + def resourceUnit: Resource[F, Unit] + } + + object Meta { + def enabled[F[_]: Applicative]: Meta[F] = make(enabled = true) + def disabled[F[_]: Applicative]: Meta[F] = make(enabled = false) + + private def make[F[_]: Applicative](enabled: Boolean): Meta[F] = + new Meta[F] { + val isEnabled: Boolean = enabled + val unit: F[Unit] = Applicative[F].unit + val resourceUnit: Resource[F, Unit] = Resource.unit + } + } + + trait Backend[F[_], A] { + def meta: Meta[F] /** Records a value with a set of attributes. * @@ -108,13 +126,12 @@ object Histogram { new Histogram[F, A] { val backend: Backend[F, A] = new Backend[F, A] { - val isEnabled: Boolean = false - val unit: F[Unit] = F.unit - def record(value: A, attributes: Attribute[_]*): F[Unit] = unit + val meta: Meta[F] = Meta.disabled + def record(value: A, attributes: Attribute[_]*): F[Unit] = meta.unit def recordDuration( timeUnit: TimeUnit, attributes: Attribute[_]* - ): Resource[F, Unit] = resourceUnit + ): Resource[F, Unit] = meta.resourceUnit } } diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/Meter.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Meter.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/Meter.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Meter.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/MeterBuilder.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/MeterBuilder.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/MeterBuilder.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/MeterBuilder.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/MeterProvider.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/MeterProvider.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/MeterProvider.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/MeterProvider.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/ObservableCounter.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableCounter.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/ObservableCounter.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableCounter.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/ObservableGauge.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableGauge.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/ObservableGauge.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableGauge.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/ObservableInstrumentBuilder.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableInstrumentBuilder.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/ObservableInstrumentBuilder.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableInstrumentBuilder.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/ObservableUpDownCounter.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableUpDownCounter.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/ObservableUpDownCounter.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/ObservableUpDownCounter.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/SyncInstrumentBuilder.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/SyncInstrumentBuilder.scala similarity index 100% rename from core/src/main/scala/org/typelevel/otel4s/metrics/SyncInstrumentBuilder.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/SyncInstrumentBuilder.scala diff --git a/core/src/main/scala/org/typelevel/otel4s/metrics/UpDownCounter.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/UpDownCounter.scala similarity index 83% rename from core/src/main/scala/org/typelevel/otel4s/metrics/UpDownCounter.scala rename to core/metrics/src/main/scala/org/typelevel/otel4s/metrics/UpDownCounter.scala index 34aee773d..e957f7e9a 100644 --- a/core/src/main/scala/org/typelevel/otel4s/metrics/UpDownCounter.scala +++ b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/UpDownCounter.scala @@ -18,6 +18,7 @@ package org.typelevel.otel4s package metrics import cats.Applicative +import org.typelevel.otel4s.meta.InstrumentMeta /** A `Counter` instrument that records values of type `A`. * @@ -37,7 +38,8 @@ trait UpDownCounter[F[_], A] extends UpDownCounterMacro[F, A] object UpDownCounter { - trait Backend[F[_], A] extends InstrumentBackend[F] { + trait Backend[F[_], A] { + def meta: InstrumentMeta[F] /** Records a value with a set of attributes. * @@ -64,9 +66,7 @@ object UpDownCounter { def dec(attributes: Attribute[_]*): F[Unit] } - abstract class LongBackend[F[_]: Applicative] extends Backend[F, Long] { - final val unit: F[Unit] = Applicative[F].unit - + trait LongBackend[F[_]] extends Backend[F, Long] { final def inc(attributes: Attribute[_]*): F[Unit] = add(1L, attributes: _*) @@ -74,9 +74,7 @@ object UpDownCounter { add(-1L, attributes: _*) } - abstract class DoubleBackend[F[_]: Applicative] extends Backend[F, Double] { - val unit: F[Unit] = Applicative[F].unit - + trait DoubleBackend[F[_]] extends Backend[F, Double] { final def inc(attributes: Attribute[_]*): F[Unit] = add(1.0, attributes: _*) @@ -88,11 +86,10 @@ object UpDownCounter { new UpDownCounter[F, A] { val backend: UpDownCounter.Backend[F, A] = new UpDownCounter.Backend[F, A] { - val unit: F[Unit] = F.unit - val isEnabled: Boolean = false - def add(value: A, attributes: Attribute[_]*): F[Unit] = unit - def inc(attributes: Attribute[_]*): F[Unit] = unit - def dec(attributes: Attribute[_]*): F[Unit] = unit + val meta: InstrumentMeta[F] = InstrumentMeta.disabled + def add(value: A, attributes: Attribute[_]*): F[Unit] = meta.unit + def inc(attributes: Attribute[_]*): F[Unit] = meta.unit + def dec(attributes: Attribute[_]*): F[Unit] = meta.unit } } diff --git a/core/src/test/scala/org/typelevel/otel4s/metrics/CounterSuite.scala b/core/metrics/src/test/scala/org/typelevel/otel4s/metrics/CounterSuite.scala similarity index 96% rename from core/src/test/scala/org/typelevel/otel4s/metrics/CounterSuite.scala rename to core/metrics/src/test/scala/org/typelevel/otel4s/metrics/CounterSuite.scala index 8d305b63d..2e49760a5 100644 --- a/core/src/test/scala/org/typelevel/otel4s/metrics/CounterSuite.scala +++ b/core/metrics/src/test/scala/org/typelevel/otel4s/metrics/CounterSuite.scala @@ -20,6 +20,7 @@ package metrics import cats.effect.IO import cats.effect.Ref import munit.CatsEffectSuite +import org.typelevel.otel4s.meta.InstrumentMeta class CounterSuite extends CatsEffectSuite { import CounterSuite._ @@ -92,7 +93,7 @@ object CounterSuite { val backend: Counter.Backend[IO, Long] = new Counter.LongBackend[IO] { - val isEnabled: Boolean = true + val meta: InstrumentMeta[IO] = InstrumentMeta.enabled def add(value: Long, attributes: Attribute[_]*): IO[Unit] = ref.update(_.appended(Record(value, attributes))) diff --git a/core/src/test/scala/org/typelevel/otel4s/metrics/HistogramSuite.scala b/core/metrics/src/test/scala/org/typelevel/otel4s/metrics/HistogramSuite.scala similarity index 98% rename from core/src/test/scala/org/typelevel/otel4s/metrics/HistogramSuite.scala rename to core/metrics/src/test/scala/org/typelevel/otel4s/metrics/HistogramSuite.scala index ebfd78a7d..c3c533679 100644 --- a/core/src/test/scala/org/typelevel/otel4s/metrics/HistogramSuite.scala +++ b/core/metrics/src/test/scala/org/typelevel/otel4s/metrics/HistogramSuite.scala @@ -100,7 +100,7 @@ object HistogramSuite { val backend: Histogram.Backend[IO, Double] = new Histogram.DoubleBackend[IO] { - val isEnabled: Boolean = true + val meta: Histogram.Meta[IO] = Histogram.Meta.enabled def record(value: Double, attributes: Attribute[_]*): IO[Unit] = ref.update(_.appended(Record(value, attributes))) diff --git a/core/src/test/scala/org/typelevel/otel4s/metrics/UpDownCounterSuite.scala b/core/metrics/src/test/scala/org/typelevel/otel4s/metrics/UpDownCounterSuite.scala similarity index 96% rename from core/src/test/scala/org/typelevel/otel4s/metrics/UpDownCounterSuite.scala rename to core/metrics/src/test/scala/org/typelevel/otel4s/metrics/UpDownCounterSuite.scala index 0b4ae6518..ebf3ee6fa 100644 --- a/core/src/test/scala/org/typelevel/otel4s/metrics/UpDownCounterSuite.scala +++ b/core/metrics/src/test/scala/org/typelevel/otel4s/metrics/UpDownCounterSuite.scala @@ -20,6 +20,7 @@ package metrics import cats.effect.IO import cats.effect.Ref import munit.CatsEffectSuite +import org.typelevel.otel4s.meta.InstrumentMeta class UpDownCounterSuite extends CatsEffectSuite { import UpDownCounterSuite._ @@ -112,7 +113,7 @@ object UpDownCounterSuite { val backend: UpDownCounter.Backend[IO, Long] = new UpDownCounter.LongBackend[IO] { - val isEnabled: Boolean = true + val meta: InstrumentMeta[IO] = InstrumentMeta.enabled def add(value: Long, attributes: Attribute[_]*): IO[Unit] = ref.update(_.appended(Record(value, attributes))) diff --git a/core/src/main/scala-2/org/typelevel/otel4s/metrics/MetricsMacro.scala b/core/src/main/scala-2/org/typelevel/otel4s/metrics/MetricsMacro.scala deleted file mode 100644 index 7a0d1a192..000000000 --- a/core/src/main/scala-2/org/typelevel/otel4s/metrics/MetricsMacro.scala +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2022 Typelevel - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.typelevel.otel4s -package metrics - -import scala.concurrent.duration.TimeUnit -import scala.reflect.macros.blackbox - -private[otel4s] object MetricsMacro { - - def add[A](c: blackbox.Context)( - value: c.Expr[A], - attributes: c.Expr[Attribute[_]]* - ): c.universe.Tree = { - import c.universe._ - val backend = q"${c.prefix}.backend" - - q"if ($backend.isEnabled) $backend.add($value, ..$attributes) else $backend.unit" - } - - def inc(c: blackbox.Context)( - attributes: c.Expr[Attribute[_]]* - ): c.universe.Tree = { - import c.universe._ - val backend = q"${c.prefix}.backend" - - q"if ($backend.isEnabled) $backend.inc(..$attributes) else $backend.unit" - } - - def dec(c: blackbox.Context)( - attributes: c.Expr[Attribute[_]]* - ): c.universe.Tree = { - import c.universe._ - val backend = q"${c.prefix}.backend" - - q"if ($backend.isEnabled) $backend.dec(..$attributes) else $backend.unit" - } - - def record[A](c: blackbox.Context)( - value: c.Expr[A], - attributes: c.Expr[Attribute[_]]* - ): c.universe.Tree = { - import c.universe._ - val backend = q"${c.prefix}.backend" - - q"if ($backend.isEnabled) $backend.record($value, ..$attributes) else $backend.unit" - } - - def recordDuration(c: blackbox.Context)( - timeUnit: c.Expr[TimeUnit], - attributes: c.Expr[Attribute[_]]* - ): c.universe.Tree = { - import c.universe._ - val backend = q"${c.prefix}.backend" - - q"if ($backend.isEnabled) $backend.recordDuration($timeUnit, ..$attributes) else $backend.resourceUnit" - } - -} diff --git a/core/src/main/scala-3/org/typelevel/otel4s/metrics/MetricsMacro.scala b/core/src/main/scala-3/org/typelevel/otel4s/metrics/MetricsMacro.scala deleted file mode 100644 index fe8e4c059..000000000 --- a/core/src/main/scala-3/org/typelevel/otel4s/metrics/MetricsMacro.scala +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2022 Typelevel - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.typelevel.otel4s -package metrics - -import scala.concurrent.duration.TimeUnit -import scala.quoted.* - -private[otel4s] object MetricsMacro { - - object counter { - - def add[F[_], A]( - backend: Expr[Counter.Backend[F, A]], - value: Expr[A], - attributes: Expr[Seq[Attribute[_]]] - )(using Quotes, Type[F], Type[A]) = - '{ - if ($backend.isEnabled) $backend.add($value, $attributes*) - else $backend.unit - } - - def inc[F[_], A]( - backend: Expr[Counter.Backend[F, A]], - attributes: Expr[Seq[Attribute[_]]] - )(using Quotes, Type[F], Type[A]) = - '{ if ($backend.isEnabled) $backend.inc($attributes*) else $backend.unit } - - } - - object upDownCounter { - - def add[F[_], A]( - backend: Expr[UpDownCounter.Backend[F, A]], - value: Expr[A], - attributes: Expr[Seq[Attribute[_]]] - )(using Quotes, Type[F], Type[A]) = - '{ - if ($backend.isEnabled) $backend.add($value, $attributes*) - else $backend.unit - } - - def inc[F[_], A]( - backend: Expr[UpDownCounter.Backend[F, A]], - attributes: Expr[Seq[Attribute[_]]] - )(using Quotes, Type[F], Type[A]) = - '{ if ($backend.isEnabled) $backend.inc($attributes*) else $backend.unit } - - def dec[F[_], A]( - backend: Expr[UpDownCounter.Backend[F, A]], - attributes: Expr[Seq[Attribute[_]]] - )(using Quotes, Type[F], Type[A]) = - '{ if ($backend.isEnabled) $backend.dec($attributes*) else $backend.unit } - - } - - object histogram { - - def record[F[_], A]( - backend: Expr[Histogram.Backend[F, A]], - value: Expr[A], - attributes: Expr[Seq[Attribute[_]]] - )(using Quotes, Type[F], Type[A]) = - '{ - if ($backend.isEnabled) $backend.record($value, $attributes*) - else $backend.unit - } - - def recordDuration[F[_], A]( - backend: Expr[Histogram.Backend[F, A]], - timeUnit: Expr[TimeUnit], - attributes: Expr[Seq[Attribute[_]]] - )(using Quotes, Type[F], Type[A]) = - '{ - if ($backend.isEnabled) $backend.recordDuration($timeUnit, $attributes*) - else $backend.resourceUnit - } - - } - -} diff --git a/java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala b/java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala new file mode 100644 index 000000000..ce761a68c --- /dev/null +++ b/java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala @@ -0,0 +1,33 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s.java + +import cats.effect.Sync +import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} +import org.typelevel.otel4s.Otel4s +import org.typelevel.otel4s.metrics.MeterProvider + +object OtelJava { + + def forSync[F[_]](jOtel: JOpenTelemetry)(implicit F: Sync[F]): Otel4s[F] = { + new Otel4s[F] { + private val metrics = Metrics.forSync(jOtel) + def meterProvider: MeterProvider[F] = metrics.meterProvider + } + } + +} diff --git a/java/common/src/main/scala/org/typelevel/otel4s/java/Conversions.scala b/java/common/src/main/scala/org/typelevel/otel4s/java/Conversions.scala new file mode 100644 index 000000000..7a2d3fe1b --- /dev/null +++ b/java/common/src/main/scala/org/typelevel/otel4s/java/Conversions.scala @@ -0,0 +1,74 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java + +import io.opentelemetry.api.common.{AttributeKey => JAttributeKey} +import io.opentelemetry.api.common.{AttributeType => JAttributeType} +import io.opentelemetry.api.common.{Attributes => JAttributes} + +import scala.jdk.CollectionConverters._ + +private[java] object Conversions { + + def toJAttributes(attributes: Seq[Attribute[_]]): JAttributes = { + val builder = JAttributes.builder + + def put(name: String, jType: JAttributeType, value: Any): Unit = { + val jKey = new JAttributeKey[Any] { + def getKey: String = name + def getType: JAttributeType = jType + override def toString: String = name + } + builder.put[Any](jKey, value) + () + } + + def putList(name: String, jType: JAttributeType, values: Any): Unit = { + val jKey = new JAttributeKey[Any] { + def getKey: String = name + def getType: JAttributeType = jType + override def toString: String = name + } + builder.put[Any](jKey, values.asInstanceOf[Seq[Any]].asJava) + () + } + + attributes.foreach { case Attribute(key, value) => + key.`type` match { + case AttributeType.String => + put(key.name, JAttributeType.STRING, value) + case AttributeType.Boolean => + put(key.name, JAttributeType.BOOLEAN, value) + case AttributeType.Long => + put(key.name, JAttributeType.LONG, value) + case AttributeType.Double => + put(key.name, JAttributeType.DOUBLE, value) + case AttributeType.StringList => + putList(key.name, JAttributeType.STRING_ARRAY, value) + case AttributeType.BooleanList => + putList(key.name, JAttributeType.BOOLEAN_ARRAY, value) + case AttributeType.LongList => + putList(key.name, JAttributeType.LONG_ARRAY, value) + case AttributeType.DoubleList => + putList(key.name, JAttributeType.DOUBLE_ARRAY, value) + } + } + builder.build() + } + +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala new file mode 100644 index 000000000..0590a3079 --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala @@ -0,0 +1,35 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s.java + +import cats.effect.Sync +import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} +import org.typelevel.otel4s.java.metrics.MeterProviderImpl +import org.typelevel.otel4s.metrics.MeterProvider + +trait Metrics[F[_]] { + def meterProvider: MeterProvider[F] +} + +object Metrics { + + def forSync[F[_]: Sync](jOtel: JOpenTelemetry): Metrics[F] = + new Metrics[F] { + val meterProvider: MeterProvider[F] = new MeterProviderImpl[F](jOtel) + } + +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala new file mode 100644 index 000000000..471d04f54 --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.metrics.{Meter => JMeter} +import org.typelevel.otel4s.metrics._ + +private[java] case class CounterBuilderImpl[F[_]]( + jMeter: JMeter, + name: String, + unit: Option[String] = None, + description: Option[String] = None +)(implicit F: Sync[F]) + extends SyncInstrumentBuilder[F, Counter[F, Long]] { + type Self = CounterBuilderImpl[F] + + def withUnit(unit: String): Self = copy(unit = Option(unit)) + + def withDescription(description: String): Self = + copy(description = Option(description)) + + def create: F[Counter[F, Long]] = F.delay { + val b = jMeter.counterBuilder(name) + unit.foreach(b.setUnit) + description.foreach(b.setDescription) + new CounterImpl(b.build) + } +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala new file mode 100644 index 000000000..ed4c619a1 --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.metrics.{LongCounter => JLongCounter} +import org.typelevel.otel4s.meta.InstrumentMeta +import org.typelevel.otel4s.metrics._ + +private[java] class CounterImpl[F[_]]( + longCounter: JLongCounter +)(implicit F: Sync[F]) + extends Counter[F, Long] { + + val backend: Counter.Backend[F, Long] = + new Counter.LongBackend[F] { + val meta: InstrumentMeta[F] = InstrumentMeta.enabled + + def add(value: Long, attributes: Attribute[_]*): F[Unit] = + F.delay(longCounter.add(value, Conversions.toJAttributes(attributes))) + } + +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala new file mode 100644 index 000000000..f6c2a0213 --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala @@ -0,0 +1,45 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.metrics.{Meter => JMeter} +import org.typelevel.otel4s.metrics._ + +private[java] case class HistogramBuilderImpl[F[_]]( + jMeter: JMeter, + name: String, + unit: Option[String] = None, + description: Option[String] = None +)(implicit F: Sync[F]) + extends SyncInstrumentBuilder[F, Histogram[F, Double]] { + type Self = HistogramBuilderImpl[F] + + def withUnit(unit: String): Self = copy(unit = Option(unit)) + + def withDescription(description: String): Self = + copy(description = Option(description)) + + def create: F[Histogram[F, Double]] = F.delay { + val b = jMeter.histogramBuilder(name) + unit.foreach(b.setUnit) + description.foreach(b.setDescription) + new HistogramImpl(b.build) + } +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala new file mode 100644 index 000000000..94844ddaf --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.metrics.{DoubleHistogram => JDoubleHistogram} +import org.typelevel.otel4s.metrics._ + +private[java] class HistogramImpl[F[_]]( + histogram: JDoubleHistogram +)(implicit F: Sync[F]) + extends Histogram[F, Double] { + + val backend: Histogram.Backend[F, Double] = + new Histogram.DoubleBackend[F] { + val meta: Histogram.Meta[F] = Histogram.Meta.enabled + + def record(value: Double, attributes: Attribute[_]*): F[Unit] = + F.delay( + histogram.record(value, Conversions.toJAttributes(attributes)) + ) + } +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala new file mode 100644 index 000000000..400734d54 --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala @@ -0,0 +1,44 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} +import org.typelevel.otel4s.metrics._ + +private[java] case class MeterBuilderImpl[F[_]]( + jOtel: JOpenTelemetry, + name: String, + version: Option[String] = None, + schemaUrl: Option[String] = None +)(implicit F: Sync[F]) + extends MeterBuilder[F] { + def withVersion(version: String): MeterBuilder[F] = + copy(version = Option(version)) + + def withSchemaUrl(schemaUrl: String): MeterBuilder[F] = + copy(schemaUrl = Option(schemaUrl)) + + def get: F[Meter[F]] = F.delay { + val b = jOtel.meterBuilder(name) + version.foreach(b.setInstrumentationVersion) + schemaUrl.foreach(b.setSchemaUrl) + new MeterImpl(b.build()) + } +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala new file mode 100644 index 000000000..0d34f181e --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala @@ -0,0 +1,38 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.metrics.{Meter => JMeter} +import org.typelevel.otel4s.metrics._ + +private[java] class MeterImpl[F[_]: Sync](jMeter: JMeter) extends Meter[F] { + def counter(name: String): SyncInstrumentBuilder[F, Counter[F, Long]] = + new CounterBuilderImpl(jMeter, name) + + def histogram( + name: String + ): SyncInstrumentBuilder[F, Histogram[F, Double]] = + new HistogramBuilderImpl(jMeter, name) + + def upDownCounter( + name: String + ): SyncInstrumentBuilder[F, UpDownCounter[F, Long]] = + new UpDownCounterBuilderImpl(jMeter, name) +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala new file mode 100644 index 000000000..c934ecc7f --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala @@ -0,0 +1,32 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} +import org.typelevel.otel4s.metrics.MeterBuilder +import org.typelevel.otel4s.metrics.MeterProvider + +private[java] class MeterProviderImpl[F[_]: Sync]( + jOtel: JOpenTelemetry +) extends MeterProvider[F] { + + def meter(name: String): MeterBuilder[F] = new MeterBuilderImpl(jOtel, name) + +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala new file mode 100644 index 000000000..2cb1a0f50 --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala @@ -0,0 +1,46 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.metrics.{Meter => JMeter} +import org.typelevel.otel4s.metrics._ + +private[java] case class UpDownCounterBuilderImpl[F[_]]( + jMeter: JMeter, + name: String, + unit: Option[String] = None, + description: Option[String] = None +)(implicit F: Sync[F]) + extends SyncInstrumentBuilder[F, UpDownCounter[F, Long]] { + type Self = UpDownCounterBuilderImpl[F] + + def withUnit(unit: String): UpDownCounterBuilderImpl[F] = + copy(unit = Option(unit)) + + def withDescription(description: String): UpDownCounterBuilderImpl[F] = + copy(description = Option(description)) + + def create: F[UpDownCounter[F, Long]] = F.delay { + val b = jMeter.upDownCounterBuilder(name) + unit.foreach(b.setUnit) + description.foreach(b.setDescription) + new UpDownCounterImpl(b.build) + } +} diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala new file mode 100644 index 000000000..f9b763860 --- /dev/null +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.otel4s +package java +package metrics + +import cats.effect.Sync +import io.opentelemetry.api.metrics.{LongUpDownCounter => JLongUpDownCounter} +import org.typelevel.otel4s.meta.InstrumentMeta +import org.typelevel.otel4s.metrics._ + +private[java] class UpDownCounterImpl[F[_]]( + counter: JLongUpDownCounter +)(implicit F: Sync[F]) + extends UpDownCounter[F, Long] { + + val backend: UpDownCounter.Backend[F, Long] = + new UpDownCounter.LongBackend[F] { + val meta: InstrumentMeta[F] = InstrumentMeta.enabled + + def add(value: Long, attributes: Attribute[_]*): F[Unit] = + F.delay(counter.add(value, Conversions.toJAttributes(attributes))) + + } +} diff --git a/java/src/test/scala/org/typelevel/otel4s/java/JavaOtelSuite.scala b/java/metrics/src/test/scala/org/typelevel/otel4s/java/metrics/CounterSuite.scala similarity index 89% rename from java/src/test/scala/org/typelevel/otel4s/java/JavaOtelSuite.scala rename to java/metrics/src/test/scala/org/typelevel/otel4s/java/metrics/CounterSuite.scala index f2ee27f2b..5f589298b 100644 --- a/java/src/test/scala/org/typelevel/otel4s/java/JavaOtelSuite.scala +++ b/java/metrics/src/test/scala/org/typelevel/otel4s/java/metrics/CounterSuite.scala @@ -16,21 +16,24 @@ package org.typelevel.otel4s package java +package metrics import cats.effect.IO import io.opentelemetry.sdk.metrics._ import munit.CatsEffectSuite import org.typelevel.otel4s.testkit._ +import org.typelevel.otel4s.testkit.metrics.MetricsSdk import scala.jdk.CollectionConverters._ -class JavaOtelSuite extends CatsEffectSuite { +class CounterSuite extends CatsEffectSuite { test("Counter record a proper data") { for { sdk <- IO.delay(makeSdk) - otel4s <- IO.delay(OtelJava.forSync[IO](sdk.sdk)) - meter <- otel4s.meterProvider + meter <- Metrics + .forSync[IO](sdk.sdk) + .meterProvider .meter("java.otel.suite") .withVersion("1.0") .withSchemaUrl("https://localhost:8080") @@ -67,7 +70,7 @@ class JavaOtelSuite extends CatsEffectSuite { assertEquals(metrics.map(_.unit), List(Some("unit"))) assertEquals( metrics.map(_.resource), - List(new MetricResource(None, resourceAttributes)) + List(new InstrumentationResource(None, resourceAttributes)) ) assertEquals(metrics.map(_.scope), List(scope)) assertEquals[List[Any], List[Any]]( @@ -77,7 +80,7 @@ class JavaOtelSuite extends CatsEffectSuite { } } - private def makeSdk: Sdk[IO] = { + private def makeSdk: MetricsSdk[IO] = { def customize(builder: SdkMeterProviderBuilder): SdkMeterProviderBuilder = builder.registerView( InstrumentSelector.builder().setType(InstrumentType.HISTOGRAM).build(), @@ -91,7 +94,7 @@ class JavaOtelSuite extends CatsEffectSuite { .build() ) - Sdk.create[IO](customize) + MetricsSdk.create[IO](customize) } private val HistogramBuckets: List[Double] = diff --git a/java/src/main/scala/org/typelevel/otel4s/java/impl.scala b/java/src/main/scala/org/typelevel/otel4s/java/impl.scala deleted file mode 100644 index b09e3d2e7..000000000 --- a/java/src/main/scala/org/typelevel/otel4s/java/impl.scala +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2022 Typelevel - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.typelevel.otel4s -package java - -import cats.effect.Sync -import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} -import io.opentelemetry.api.common.{AttributeKey => JAttributeKey} -import io.opentelemetry.api.common.{AttributeType => JAttributeType} -import io.opentelemetry.api.common.{Attributes => JAttributes} -import io.opentelemetry.api.metrics.{DoubleHistogram => JDoubleHistogram} -import io.opentelemetry.api.metrics.{LongCounter => JLongCounter} -import io.opentelemetry.api.metrics.{LongUpDownCounter => JLongUpDownCounter} -import io.opentelemetry.api.metrics.{Meter => JMeter} -import org.typelevel.otel4s.metrics._ - -import scala.jdk.CollectionConverters._ - -object OtelJava { - def forSync[F[_]](jOtel: JOpenTelemetry)(implicit F: Sync[F]): Otel4s[F] = - new Otel4s[F] { - def meterProvider: MeterProvider[F] = new MeterProviderImpl[F](jOtel) - } - - private class MeterProviderImpl[F[_]: Sync](jOtel: JOpenTelemetry) - extends MeterProvider[F] { - def meter(name: String): MeterBuilder[F] = new MeterBuilderImpl(jOtel, name) - } - - private case class MeterBuilderImpl[F[_]]( - jOtel: JOpenTelemetry, - name: String, - version: Option[String] = None, - schemaUrl: Option[String] = None - )(implicit F: Sync[F]) - extends MeterBuilder[F] { - def withVersion(version: String): MeterBuilder[F] = - copy(version = Option(version)) - def withSchemaUrl(schemaUrl: String): MeterBuilder[F] = - copy(schemaUrl = Option(schemaUrl)) - - def get: F[Meter[F]] = F.delay { - val b = jOtel.meterBuilder(name) - version.foreach(b.setInstrumentationVersion) - schemaUrl.foreach(b.setSchemaUrl) - new MeterImpl(b.build()) - } - } - - private class MeterImpl[F[_]: Sync](jMeter: JMeter) extends Meter[F] { - def counter(name: String): SyncInstrumentBuilder[F, Counter[F, Long]] = - new CounterBuilderImpl(jMeter, name) - - def histogram( - name: String - ): SyncInstrumentBuilder[F, Histogram[F, Double]] = - new HistogramBuilderImpl(jMeter, name) - - def upDownCounter( - name: String - ): SyncInstrumentBuilder[F, UpDownCounter[F, Long]] = - new UpDownCounterBuilderImpl(jMeter, name) - } - - private case class CounterBuilderImpl[F[_]]( - jMeter: JMeter, - name: String, - unit: Option[String] = None, - description: Option[String] = None - )(implicit F: Sync[F]) - extends SyncInstrumentBuilder[F, Counter[F, Long]] { - type Self = CounterBuilderImpl[F] - - def withUnit(unit: String): Self = copy(unit = Option(unit)) - def withDescription(description: String): Self = - copy(description = Option(description)) - - def create: F[Counter[F, Long]] = F.delay { - val b = jMeter.counterBuilder(name) - unit.foreach(b.setUnit) - description.foreach(b.setDescription) - new CounterImpl(b.build) - } - } - - private class CounterImpl[F[_]](longCounter: JLongCounter)(implicit - F: Sync[F] - ) extends Counter[F, Long] { - - val backend: Counter.Backend[F, Long] = - new Counter.LongBackend[F] { - val isEnabled: Boolean = true - - def add(value: Long, attributes: Attribute[_]*): F[Unit] = - F.delay(longCounter.add(value, toJAttributes(attributes))) - } - - } - - private case class HistogramBuilderImpl[F[_]]( - jMeter: JMeter, - name: String, - unit: Option[String] = None, - description: Option[String] = None - )(implicit F: Sync[F]) - extends SyncInstrumentBuilder[F, Histogram[F, Double]] { - type Self = HistogramBuilderImpl[F] - - def withUnit(unit: String): Self = copy(unit = Option(unit)) - def withDescription(description: String): Self = - copy(description = Option(description)) - - def create: F[Histogram[F, Double]] = F.delay { - val b = jMeter.histogramBuilder(name) - unit.foreach(b.setUnit) - description.foreach(b.setDescription) - new HistogramImpl(b.build) - } - } - - private class HistogramImpl[F[_]](histogram: JDoubleHistogram)(implicit - F: Sync[F] - ) extends Histogram[F, Double] { - - val backend: Histogram.Backend[F, Double] = - new Histogram.DoubleBackend[F] { - val isEnabled: Boolean = true - def record(value: Double, attributes: Attribute[_]*): F[Unit] = - F.delay(histogram.record(value, toJAttributes(attributes))) - } - } - - private case class UpDownCounterBuilderImpl[F[_]]( - jMeter: JMeter, - name: String, - unit: Option[String] = None, - description: Option[String] = None - )(implicit F: Sync[F]) - extends SyncInstrumentBuilder[F, UpDownCounter[F, Long]] { - type Self = UpDownCounterBuilderImpl[F] - - def withUnit(unit: String) = - copy(unit = Option(unit)) - - def withDescription(description: String) = - copy(description = Option(description)) - - def create: F[UpDownCounter[F, Long]] = F.delay { - val b = jMeter.upDownCounterBuilder(name) - unit.foreach(b.setUnit) - description.foreach(b.setDescription) - new UpDownCounterImpl(b.build) - } - } - - private class UpDownCounterImpl[F[_]](counter: JLongUpDownCounter)(implicit - F: Sync[F] - ) extends UpDownCounter[F, Long] { - - val backend: UpDownCounter.Backend[F, Long] = - new UpDownCounter.LongBackend[F] { - val isEnabled: Boolean = true - - def add(value: Long, attributes: Attribute[_]*): F[Unit] = - F.delay(counter.add(value, toJAttributes(attributes))) - - } - } - - private def toJAttributes(attributes: Seq[Attribute[_]]): JAttributes = { - val builder = JAttributes.builder - def put(name: String, jType: JAttributeType, value: Any): Unit = { - val jKey = new JAttributeKey[Any] { - def getKey = name - def getType = jType - override def toString = name - } - builder.put[Any](jKey, value) - () - } - def putList(name: String, jType: JAttributeType, values: Any): Unit = { - val jKey = new JAttributeKey[Any] { - def getKey = name - def getType = jType - override def toString = name - } - builder.put[Any](jKey, values.asInstanceOf[Seq[Any]].asJava) - () - } - attributes.foreach { case Attribute(key, value) => - key.`type` match { - case AttributeType.String => - put(key.name, JAttributeType.STRING, value) - case AttributeType.Boolean => - put(key.name, JAttributeType.BOOLEAN, value) - case AttributeType.Long => - put(key.name, JAttributeType.LONG, value) - case AttributeType.Double => - put(key.name, JAttributeType.DOUBLE, value) - case AttributeType.StringList => - putList(key.name, JAttributeType.STRING_ARRAY, value) - case AttributeType.BooleanList => - putList(key.name, JAttributeType.BOOLEAN_ARRAY, value) - case AttributeType.LongList => - putList(key.name, JAttributeType.LONG_ARRAY, value) - case AttributeType.DoubleList => - putList(key.name, JAttributeType.DOUBLE_ARRAY, value) - } - } - builder.build() - } -} diff --git a/java/src/test/scala/com/example/PoC.scala b/java/src/test/scala/com/example/PoC.scala deleted file mode 100644 index abe3f6fe2..000000000 --- a/java/src/test/scala/com/example/PoC.scala +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2022 Typelevel - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.example - -import cats.effect.IO -import cats.effect.IOApp -import cats.syntax.foldable._ -import io.opentelemetry.sdk.OpenTelemetrySdk -import io.opentelemetry.sdk.metrics.SdkMeterProvider -import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader -import org.typelevel.otel4s.Attribute -import org.typelevel.otel4s.AttributeKey -import org.typelevel.otel4s.java.OtelJava - -import scala.jdk.CollectionConverters._ - -object Poc extends IOApp.Simple { - - def run: IO[Unit] = for { - jMetricReader <- IO(InMemoryMetricReader.create()) - otel4j <- IO { - val meterProvider = SdkMeterProvider - .builder() - .registerMetricReader(jMetricReader) - .build() - - val sdk = OpenTelemetrySdk - .builder() - .setMeterProvider(meterProvider) - .build() - - sdk - } - otel4s = OtelJava.forSync[IO](otel4j) - meter <- otel4s.meterProvider.get("poc") - counter <- meter.counter("test").create - _ <- counter.add(1) - dog = AttributeKey.string("dog") - fish = AttributeKey.stringList("fish") - numbers = AttributeKey.longList("numbers") - _ <- counter.add( - 2, - Attribute(dog, "barking"), - Attribute(fish, List("one", "two", "red", "blue")), - Attribute(numbers, List(1L, 2L, 3L, 4L)) - ) - _ <- jMetricReader.collectAllMetrics().asScala.toList.traverse_(IO.println) - } yield () -} diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/Implicits.scala b/testkit/common/shared/src/main/scala/org/typelevel/otel4s/testkit/Implicits.scala similarity index 100% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/Implicits.scala rename to testkit/common/shared/src/main/scala/org/typelevel/otel4s/testkit/Implicits.scala diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/MetricResource.scala b/testkit/common/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationResource.scala similarity index 67% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/MetricResource.scala rename to testkit/common/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationResource.scala index 1505292c0..3418e4e85 100644 --- a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/MetricResource.scala +++ b/testkit/common/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationResource.scala @@ -21,34 +21,36 @@ import cats.Hash import cats.Show import cats.syntax.show._ -final class MetricResource( +final class InstrumentationResource( val schemaUrl: Option[String], val attributes: List[Attribute[_]] ) { override def hashCode(): Int = - Hash[MetricResource].hash(this) + Hash[InstrumentationResource].hash(this) override def toString: String = - Show[MetricResource].show(this) + Show[InstrumentationResource].show(this) override def equals(obj: Any): Boolean = obj match { - case other: MetricResource => - Hash[MetricResource].eqv(this, other) + case other: InstrumentationResource => + Hash[InstrumentationResource].eqv(this, other) case _ => false } } -object MetricResource { +object InstrumentationResource { import Implicits._ - implicit val metricResourceHash: Hash[MetricResource] = + implicit val metricResourceHash: Hash[InstrumentationResource] = Hash.by(p => (p.schemaUrl, p.attributes)) - implicit val metricResourceShow: Show[MetricResource] = - Show.show(p => show"MetricResource(${p.schemaUrl}, ${p.attributes})") + implicit val metricResourceShow: Show[InstrumentationResource] = + Show.show(p => + show"InstrumentationResource(${p.schemaUrl}, ${p.attributes})" + ) } diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationScope.scala b/testkit/common/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationScope.scala similarity index 100% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationScope.scala rename to testkit/common/shared/src/main/scala/org/typelevel/otel4s/testkit/InstrumentationScope.scala diff --git a/testkit/jvm/src/main/scala/org/typelevel/otel4s/testkit/Sdk.scala b/testkit/metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala similarity index 97% rename from testkit/jvm/src/main/scala/org/typelevel/otel4s/testkit/Sdk.scala rename to testkit/metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala index acf821b70..ad77febbb 100644 --- a/testkit/jvm/src/main/scala/org/typelevel/otel4s/testkit/Sdk.scala +++ b/testkit/metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala @@ -16,6 +16,7 @@ package org.typelevel.otel4s package testkit +package metrics import cats.effect.Sync import io.opentelemetry.api.common.{AttributeType => JAttributeType} @@ -39,16 +40,16 @@ import java.{lang => jl} import java.{util => ju} import scala.jdk.CollectionConverters._ -trait Sdk[F[_]] { +trait MetricsSdk[F[_]] { def sdk: OpenTelemetrySdk def metrics: F[List[Metric]] } -object Sdk { +object MetricsSdk { def create[F[_]: Sync]( customize: SdkMeterProviderBuilder => SdkMeterProviderBuilder = identity - ): Sdk[F] = { + ): MetricsSdk[F] = { val metricReader = InMemoryMetricReader.create() val meterProviderBuilder = SdkMeterProvider @@ -62,7 +63,7 @@ object Sdk { .setMeterProvider(meterProvider) .build() - new Sdk[F] { + new MetricsSdk[F] { val sdk: OpenTelemetrySdk = openTelemetrySdk def metrics: F[List[Metric]] = @@ -173,7 +174,7 @@ object Sdk { version = Option(scope.getVersion), schemaUrl = Option(scope.getSchemaUrl) ), - resource = new MetricResource( + resource = new InstrumentationResource( schemaUrl = Option(resource.getSchemaUrl), attributes = collectAttributes(resource.getAttributes) ), diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/HistogramPointData.scala b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/HistogramPointData.scala similarity index 97% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/HistogramPointData.scala rename to testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/HistogramPointData.scala index ffd3fcdbb..f2bcc384a 100644 --- a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/HistogramPointData.scala +++ b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/HistogramPointData.scala @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.typelevel.otel4s.testkit +package org.typelevel.otel4s.testkit.metrics import cats.Hash import cats.Show diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/Metric.scala b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/Metric.scala similarity index 96% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/Metric.scala rename to testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/Metric.scala index 80d02f3fa..b6f7d0a34 100644 --- a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/Metric.scala +++ b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/Metric.scala @@ -15,6 +15,7 @@ */ package org.typelevel.otel4s.testkit +package metrics import cats.Hash import cats.Show @@ -25,7 +26,7 @@ final class Metric( val description: Option[String], val unit: Option[String], val scope: InstrumentationScope, - val resource: MetricResource, + val resource: InstrumentationResource, val data: MetricData ) { diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/MetricData.scala b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricData.scala similarity index 98% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/MetricData.scala rename to testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricData.scala index ccd7d9230..f4dc21df4 100644 --- a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/MetricData.scala +++ b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricData.scala @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.typelevel.otel4s.testkit +package org.typelevel.otel4s.testkit.metrics import cats.Hash import cats.Show diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/PointData.scala b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/PointData.scala similarity index 98% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/PointData.scala rename to testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/PointData.scala index 80392cda9..3649f1f0c 100644 --- a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/PointData.scala +++ b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/PointData.scala @@ -16,6 +16,7 @@ package org.typelevel.otel4s package testkit +package metrics import cats.Hash import cats.Show diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/QuantileData.scala b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/QuantileData.scala similarity index 96% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/QuantileData.scala rename to testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/QuantileData.scala index 73b35ff5f..cd73ddeec 100644 --- a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/QuantileData.scala +++ b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/QuantileData.scala @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.typelevel.otel4s.testkit +package org.typelevel.otel4s.testkit.metrics import cats.Hash import cats.Show diff --git a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/SummaryPointData.scala b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/SummaryPointData.scala similarity index 96% rename from testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/SummaryPointData.scala rename to testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/SummaryPointData.scala index 34cbba560..055fb951a 100644 --- a/testkit/shared/src/main/scala/org/typelevel/otel4s/testkit/SummaryPointData.scala +++ b/testkit/metrics/shared/src/main/scala/org/typelevel/otel4s/testkit/metrics/SummaryPointData.scala @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.typelevel.otel4s.testkit +package org.typelevel.otel4s.testkit.metrics import cats.Hash import cats.Show From f24f9dae449aa64e0700d0a587bb52f9d2ceb54a Mon Sep 17 00:00:00 2001 From: Maksim Ochenashko Date: Wed, 3 Aug 2022 14:52:49 +0300 Subject: [PATCH 2/3] Do not use `crossProject` with `java` modules --- .github/workflows/ci.yml | 4 ++-- build.sbt | 15 ++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a26a224f..c52d3f665 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,11 +94,11 @@ jobs: - name: Make target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: mkdir -p testkit/metrics/jvm/target testkit/common/jvm/target target java/common/.jvm/target core/common/.jvm/target .js/target site/target core/metrics/.jvm/target java/metrics/.jvm/target core/all/.js/target core/metrics/.js/target core/all/.jvm/target .jvm/target .native/target core/common/.js/target java/all/.jvm/target testkit/all/jvm/target project/target + run: mkdir -p testkit/metrics/jvm/target java/metrics/target testkit/common/jvm/target target core/common/.jvm/target .js/target site/target core/metrics/.jvm/target core/all/.js/target java/all/target java/common/target core/metrics/.js/target core/all/.jvm/target .jvm/target .native/target core/common/.js/target testkit/all/jvm/target project/target - name: Compress target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: tar cf targets.tar testkit/metrics/jvm/target testkit/common/jvm/target target java/common/.jvm/target core/common/.jvm/target .js/target site/target core/metrics/.jvm/target java/metrics/.jvm/target core/all/.js/target core/metrics/.js/target core/all/.jvm/target .jvm/target .native/target core/common/.js/target java/all/.jvm/target testkit/all/jvm/target project/target + run: tar cf targets.tar testkit/metrics/jvm/target java/metrics/target testkit/common/jvm/target target core/common/.jvm/target .js/target site/target core/metrics/.jvm/target core/all/.js/target java/all/target java/common/target core/metrics/.js/target core/all/.jvm/target .jvm/target .native/target core/common/.js/target testkit/all/jvm/target project/target - name: Upload target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') diff --git a/build.sbt b/build.sbt index 1f04f66c1..ce94f7877 100644 --- a/build.sbt +++ b/build.sbt @@ -113,10 +113,9 @@ lazy val testkit = crossProject(JVMPlatform) name := "otel4s-testkit" ) -lazy val `java-common` = crossProject(JVMPlatform) - .crossType(CrossType.Pure) +lazy val `java-common` = project .in(file("java/common")) - .dependsOn(`core-common`, `testkit-common`) + .dependsOn(`core-common`.jvm, `testkit-common`.jvm) .settings( name := "otel4s-java-common", libraryDependencies ++= Seq( @@ -124,10 +123,9 @@ lazy val `java-common` = crossProject(JVMPlatform) ) ) -lazy val `java-metrics` = crossProject(JVMPlatform) - .crossType(CrossType.Pure) +lazy val `java-metrics` = project .in(file("java/metrics")) - .dependsOn(`java-common`, `core-metrics`, `testkit-metrics`) + .dependsOn(`java-common`, `core-metrics`.jvm, `testkit-metrics`.jvm) .settings( name := "otel4s-java-metrics", libraryDependencies ++= Seq( @@ -139,10 +137,9 @@ lazy val `java-metrics` = crossProject(JVMPlatform) ) ) -lazy val java = crossProject(JVMPlatform) - .crossType(CrossType.Pure) +lazy val java = project .in(file("java/all")) - .dependsOn(core, `java-metrics`) + .dependsOn(core.jvm, `java-metrics`) .settings( name := "otel4s-java" ) From 0d3235c0ae8195239d4812effed2f9ffa9221975 Mon Sep 17 00:00:00 2001 From: Maksim Ochenashko Date: Wed, 3 Aug 2022 18:34:35 +0300 Subject: [PATCH 3/3] Use `cats-effect-kernel` in `core-metrics` module --- build.sbt | 2 +- .../scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala | 2 +- .../scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala | 2 +- .../main/scala/org/typelevel/otel4s/metrics/Histogram.scala | 4 ++-- .../src/main/scala/org/typelevel/otel4s/java/OtelJava.scala | 2 +- .../src/main/scala/org/typelevel/otel4s/java/Metrics.scala | 2 +- .../typelevel/otel4s/java/metrics/CounterBuilderImpl.scala | 2 +- .../scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala | 2 +- .../typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala | 2 +- .../org/typelevel/otel4s/java/metrics/HistogramImpl.scala | 2 +- .../org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala | 2 +- .../scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala | 2 +- .../org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala | 2 +- .../otel4s/java/metrics/UpDownCounterBuilderImpl.scala | 2 +- .../org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala | 2 +- .../org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala | 2 +- 16 files changed, 17 insertions(+), 17 deletions(-) diff --git a/build.sbt b/build.sbt index ce94f7877..07925aafc 100644 --- a/build.sbt +++ b/build.sbt @@ -67,7 +67,7 @@ lazy val `core-metrics` = crossProject(JVMPlatform, JSPlatform) .settings( name := "otel4s-core-metrics", libraryDependencies ++= Seq( - "org.typelevel" %%% "cats-effect" % CatsEffectVersion, + "org.typelevel" %%% "cats-effect-kernel" % CatsEffectVersion, "org.scalameta" %%% "munit" % MUnitVersion % Test, "org.typelevel" %%% "munit-cats-effect-3" % MUnitCatsEffectVersion % Test, "org.typelevel" %%% "cats-effect-testkit" % CatsEffectVersion % Test diff --git a/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala index e40346866..168fc3a01 100644 --- a/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala +++ b/core/metrics/src/main/scala-2/org/typelevel/otel4s/metrics/HistogramMacro.scala @@ -17,7 +17,7 @@ package org.typelevel.otel4s package metrics -import cats.effect.Resource +import cats.effect.kernel.Resource import scala.concurrent.duration.TimeUnit diff --git a/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala index ad964d627..7132551da 100644 --- a/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala +++ b/core/metrics/src/main/scala-3/org/typelevel/otel4s/metrics/HistogramMacro.scala @@ -17,7 +17,7 @@ package org.typelevel.otel4s package metrics -import cats.effect.Resource +import cats.effect.kernel.Resource import scala.concurrent.duration._ import scala.quoted.* diff --git a/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala index ec7e97bfa..71fd4d2b2 100644 --- a/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala +++ b/core/metrics/src/main/scala/org/typelevel/otel4s/metrics/Histogram.scala @@ -19,8 +19,8 @@ package metrics import cats.Applicative import cats.Monad -import cats.effect.Clock -import cats.effect.Resource +import cats.effect.kernel.Clock +import cats.effect.kernel.Resource import cats.syntax.flatMap._ import cats.syntax.functor._ import org.typelevel.otel4s.meta.InstrumentMeta diff --git a/java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala b/java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala index ce761a68c..c57e4a7a3 100644 --- a/java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala +++ b/java/all/src/main/scala/org/typelevel/otel4s/java/OtelJava.scala @@ -16,7 +16,7 @@ package org.typelevel.otel4s.java -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} import org.typelevel.otel4s.Otel4s import org.typelevel.otel4s.metrics.MeterProvider diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala index 0590a3079..dff6c032b 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/Metrics.scala @@ -16,7 +16,7 @@ package org.typelevel.otel4s.java -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} import org.typelevel.otel4s.java.metrics.MeterProviderImpl import org.typelevel.otel4s.metrics.MeterProvider diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala index 471d04f54..08ae3a63f 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterBuilderImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.metrics.{Meter => JMeter} import org.typelevel.otel4s.metrics._ diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala index ed4c619a1..1744c91de 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/CounterImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.metrics.{LongCounter => JLongCounter} import org.typelevel.otel4s.meta.InstrumentMeta import org.typelevel.otel4s.metrics._ diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala index f6c2a0213..7392d3b7a 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramBuilderImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.metrics.{Meter => JMeter} import org.typelevel.otel4s.metrics._ diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala index 94844ddaf..29b9332f6 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/HistogramImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.metrics.{DoubleHistogram => JDoubleHistogram} import org.typelevel.otel4s.metrics._ diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala index 400734d54..2a43f2f4e 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterBuilderImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} import org.typelevel.otel4s.metrics._ diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala index 0d34f181e..bfcc97838 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.metrics.{Meter => JMeter} import org.typelevel.otel4s.metrics._ diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala index c934ecc7f..158d83a5b 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/MeterProviderImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.{OpenTelemetry => JOpenTelemetry} import org.typelevel.otel4s.metrics.MeterBuilder import org.typelevel.otel4s.metrics.MeterProvider diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala index 2cb1a0f50..a9a806031 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterBuilderImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.metrics.{Meter => JMeter} import org.typelevel.otel4s.metrics._ diff --git a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala index f9b763860..9894c3c66 100644 --- a/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala +++ b/java/metrics/src/main/scala/org/typelevel/otel4s/java/metrics/UpDownCounterImpl.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package java package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.metrics.{LongUpDownCounter => JLongUpDownCounter} import org.typelevel.otel4s.meta.InstrumentMeta import org.typelevel.otel4s.metrics._ diff --git a/testkit/metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala b/testkit/metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala index ad77febbb..632ab8ed8 100644 --- a/testkit/metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala +++ b/testkit/metrics/jvm/src/main/scala/org/typelevel/otel4s/testkit/metrics/MetricsSdk.scala @@ -18,7 +18,7 @@ package org.typelevel.otel4s package testkit package metrics -import cats.effect.Sync +import cats.effect.kernel.Sync import io.opentelemetry.api.common.{AttributeType => JAttributeType} import io.opentelemetry.api.common.{Attributes => JAttributes} import io.opentelemetry.sdk.OpenTelemetrySdk