Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Versions.zioHttp
import com.softwaremill.Publish.{ossPublishSettings, updateDocs}
import com.softwaremill.SbtSoftwareMillBrowserTestJS._
import com.softwaremill.SbtSoftwareMillCommon.commonSmlBuildSettings
Expand Down Expand Up @@ -192,6 +193,7 @@ lazy val rawAllAggregates = core.projectRefs ++
opentelemetryTracing.projectRefs ++
otel4sMetrics.projectRefs ++
otel4sTracing.projectRefs ++
zioTracing.projectRefs ++
json4s.projectRefs ++
playJson.projectRefs ++
play29Json.projectRefs ++
Expand Down Expand Up @@ -1177,6 +1179,29 @@ lazy val otel4sMetrics: ProjectMatrix = (projectMatrix in file("metrics/otel4s-m
.jvmPlatform(scalaVersions = scala2_13And3Versions, settings = commonJvmSettings)
.dependsOn(serverCore % CompileAndTest, catsEffect % Test)

lazy val zioTracing: ProjectMatrix = (projectMatrix in file("tracing/zio-tracing"))
.dependsOn(zio)
.settings(commonSettings)
.settings(
name := "tapir-zio-tracing",
libraryDependencies ++= Seq(
"dev.zio" %% "zio-opentelemetry" % Versions.zioOpenTelemetry,
"dev.zio" %% "zio-opentelemetry-zio-logging" % Versions.zioOpenTelemetry,
"io.opentelemetry.semconv" % "opentelemetry-semconv" % Versions.openTelemetrySemconvVersion,
"io.opentelemetry" % "opentelemetry-sdk" % Versions.openTelemetry,
"io.opentelemetry" % "opentelemetry-exporter-otlp" % Versions.openTelemetry,
"io.opentelemetry" % "opentelemetry-exporter-logging-otlp" % Versions.openTelemetry,
"io.opentelemetry.instrumentation" % "opentelemetry-runtime-telemetry-java17" % Versions.openTelemetryRuntime,

"dev.zio" %% "zio-test" % Versions.zio % Test,
"dev.zio" %% "zio-test-sbt" % Versions.zio % Test,

"io.opentelemetry" % "opentelemetry-sdk-testing" % Versions.openTelemetry % Test
)
)
.jvmPlatform(scalaVersions = scala2_13And3Versions, settings = commonJvmSettings)
.dependsOn(serverCore % CompileAndTest)

// docs

lazy val apispecDocs: ProjectMatrix = (projectMatrix in file("docs/apispec-docs"))
Expand Down
2 changes: 2 additions & 0 deletions project/Versions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ object Versions {
val zioInteropCats = "23.1.0.13"
val zioInteropReactiveStreams = "2.0.2"
val zioJson = "0.7.44"
val zioOpenTelemetry = "3.1.15"
val playClient = "3.0.10"
val playServer = "3.0.10"
val play29Client = "2.2.14"
Expand All @@ -64,6 +65,7 @@ object Versions {
val decline = "2.6.2"
val quicklens = "1.9.12"
val openTelemetry = "1.61.0"
val openTelemetryRuntime = "2.27.0-alpha"
val openTelemetrySemconvVersion = "1.41.0"
val mockServer = "5.15.0"
val dogstatsdClient = "4.4.5"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sttp.tapir.server.tracing.ziotel

import io.opentelemetry.api.common.Attributes

import io.opentelemetry.sdk.logs.SdkLoggerProvider
import io.opentelemetry.sdk.logs.`export`.SimpleLogRecordProcessor
import io.opentelemetry.sdk.resources.Resource
import zio._

import io.opentelemetry.semconv.ServiceAttributes
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter

object LoggerProvider {

/** Prints to stdout in OTLP gRPC format
*/
def grpc(resourceName: String): RIO[Scope, SdkLoggerProvider] =
for {
logRecordExporter <-
ZIO.fromAutoCloseable(
ZIO.succeed(
OtlpGrpcLogRecordExporter
.builder()
.build()
)
)
logRecordProcessor <-
ZIO.fromAutoCloseable(
ZIO.succeed(SimpleLogRecordProcessor.create(logRecordExporter))
)
loggerProvider <-
ZIO.fromAutoCloseable(
ZIO.succeed(
SdkLoggerProvider
.builder()
.setResource(
Resource.create(
Attributes.of(ServiceAttributes.SERVICE_NAME, resourceName)
)
)
.addLogRecordProcessor(logRecordProcessor)
.build()
)
)
} yield loggerProvider

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package sttp.tapir.server.tracing.ziotel

import zio._
import io.opentelemetry.sdk.metrics.SdkMeterProvider
import io.opentelemetry.sdk.metrics.`export`.PeriodicMetricReader
import io.opentelemetry.sdk.resources.Resource
import io.opentelemetry.api.common.Attributes
import io.opentelemetry.semconv.ServiceAttributes
import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingMetricExporter
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter

object MeterProvider {

/** Prints to stdout in OTLP Json format
*/
def stdout(resourceName: String): RIO[Scope, SdkMeterProvider] =
for {
metricExporter <- ZIO.fromAutoCloseable(
ZIO.succeed(OtlpJsonLoggingMetricExporter.create())
)
metricReader <-
ZIO.fromAutoCloseable(
ZIO.succeed(
PeriodicMetricReader
.builder(metricExporter)
.setInterval(5.second)
.build()
)
)
meterProvider <-
ZIO.fromAutoCloseable(
ZIO.succeed(
SdkMeterProvider
.builder()
.registerMetricReader(metricReader)
.setResource(
Resource.create(
Attributes.of(ServiceAttributes.SERVICE_NAME, resourceName)
)
)
.build()
)
)
} yield meterProvider

def grpc(resourceName: String): RIO[Scope, SdkMeterProvider] =
for {
metricExporter <- ZIO.fromAutoCloseable(
ZIO.succeed(OtlpGrpcMetricExporter.builder().build())
)
metricReader <-
ZIO.fromAutoCloseable(
ZIO.succeed(
PeriodicMetricReader
.builder(metricExporter)
.setInterval(5.second)
.build()
)
)
meterProvider <-
ZIO.fromAutoCloseable(
ZIO.succeed(
SdkMeterProvider
.builder()
.registerMetricReader(metricReader)
.setResource(
Resource.create(
Attributes.of(ServiceAttributes.SERVICE_NAME, resourceName)
)
)
.build()
)
)
} yield meterProvider

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package sttp.tapir.server.tracing.ziotel

import io.opentelemetry.api.common.Attributes
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter
import io.opentelemetry.sdk.resources.Resource
import io.opentelemetry.sdk.trace.SdkTracerProvider
import io.opentelemetry.sdk.trace.`export`.SimpleSpanProcessor
import io.opentelemetry.semconv.ServiceAttributes
import zio._
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter
import io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingSpanExporter

object TracerProvider {

/** Prints to stdout in OTLP Json format
*/
def stdout(resourceName: String): RIO[Scope, SdkTracerProvider] =
for {
spanExporter <-
ZIO.fromAutoCloseable(ZIO.succeed(OtlpJsonLoggingSpanExporter.create()))
spanProcessor <- ZIO.fromAutoCloseable(
ZIO.succeed(SimpleSpanProcessor.create(spanExporter))
)
tracerProvider <-
ZIO.fromAutoCloseable(
ZIO.succeed(
SdkTracerProvider
.builder()
.setResource(
Resource.create(
Attributes.of(ServiceAttributes.SERVICE_NAME, resourceName)
)
)
.addSpanProcessor(spanProcessor)
.build()
)
)
} yield tracerProvider

/** https://www.jaegertracing.io/
*/
def grpc(resourceName: String): RIO[Scope, SdkTracerProvider] =
for {
spanExporter <- ZIO.fromAutoCloseable(
ZIO.succeed(OtlpGrpcSpanExporter.builder().build())
)
spanProcessor <- ZIO.fromAutoCloseable(
ZIO.succeed(SimpleSpanProcessor.create(spanExporter))
)
tracerProvider <-
ZIO.fromAutoCloseable(
ZIO.succeed(
SdkTracerProvider
.builder()
.setResource(
Resource.create(
Attributes.of(ServiceAttributes.SERVICE_NAME, resourceName)
)
)
.addSpanProcessor(spanProcessor)
.build()
)
)
} yield tracerProvider

/** https://fluentbit.io/
*/
def fluentbit(resourceName: String): RIO[Scope, SdkTracerProvider] =
for {
spanExporter <- ZIO.fromAutoCloseable(
ZIO.succeed(OtlpHttpSpanExporter.builder().build())
)
spanProcessor <- ZIO.fromAutoCloseable(
ZIO.succeed(SimpleSpanProcessor.create(spanExporter))
)
tracerProvider <-
ZIO.fromAutoCloseable(
ZIO.succeed(
SdkTracerProvider
.builder()
.setResource(
Resource.create(
Attributes.of(ServiceAttributes.SERVICE_NAME, resourceName)
)
)
.addSpanProcessor(spanProcessor)
.build()
)
)
} yield tracerProvider

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package sttp.tapir.server.tracing.ziotel

import zio._
import zio.telemetry.opentelemetry.OpenTelemetry
import io.opentelemetry.sdk.OpenTelemetrySdk
import io.opentelemetry.api

import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry

object ZIOtelSdk {

def custom(resourceName: String): TaskLayer[api.OpenTelemetry] =
OpenTelemetry.custom(
for {

tracerProvider <- TracerProvider.grpc(resourceName)
meterProvider <- MeterProvider.grpc(resourceName)
loggerProvider <- LoggerProvider.grpc(resourceName)
openTelemetry <- ZIO.fromAutoCloseable(
ZIO.succeed(
OpenTelemetrySdk
.builder()
.setTracerProvider(tracerProvider)
.setMeterProvider(meterProvider)
.setLoggerProvider(loggerProvider)
.build
)
)
_ <- ZIO.fromAutoCloseable(
ZIO.succeed(RuntimeTelemetry.create(openTelemetry))
)
} yield openTelemetry
)

}
Loading
Loading