Last active
February 21, 2025 17:45
-
-
Save calvinlfer/ef0bd9e930e2f794ca7d6bf74c64e7c9 to your computer and use it in GitHub Desktop.
Ship ZIO Metrics to OpenTelemetry (OLTP gRPC) using zio-telemetry-opentelemetry by manually providing the instrumentation (this portion connects ZIO Metrics to the ZIO Opentelemetry machinery). I also have an example that uses auto-instrumentation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val scala3Version = "3.6.3" | |
lazy val root = project | |
.in(file(".")) | |
.settings( | |
name := "zio-telemetry-playground", | |
version := "0.1.0-SNAPSHOT", | |
scalaVersion := scala3Version, | |
libraryDependencies ++= | |
Seq( | |
"dev.zio" %% "zio" % "2.1.15", | |
"dev.zio" %% "zio-logging-slf4j-bridge" % "2.4.0", // route all SLF4J logs to ZIO RTS | |
"dev.zio" %% "zio-opentelemetry" % "3.1.1", // integration for OTLP metrics + ZIO | |
"dev.zio" %% "zio-opentelemetry-zio-logging" % "3.1.1", // integration for OTLP logs + ZIO | |
"io.opentelemetry" % "opentelemetry-sdk" % "1.47.0", | |
"io.opentelemetry" % "opentelemetry-exporter-otlp" % "1.47.0" | |
) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
services: | |
otel-lgtm: | |
image: grafana/otel-lgtm:latest | |
container_name: otel-lgtm | |
ports: | |
- "3000:3000" # Grafana UI | |
- "4317:4317" # OpenTelemetry Collector gRPC | |
- "4318:4318" # OpenTelemetry Collector HTTP | |
volumes: | |
- ./otel-lgtm-data:/var/lib/grafana |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import zio.* | |
import zio.telemetry.opentelemetry.OpenTelemetry | |
import io.opentelemetry.sdk.OpenTelemetrySdk | |
import io.opentelemetry.api.metrics.MeterProvider | |
import io.opentelemetry.sdk.metrics.SdkMeterProvider | |
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter | |
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter | |
import io.opentelemetry.sdk.metrics.`export`.PeriodicMetricReader | |
import io.opentelemetry.sdk.resources.Resource as OltpResource | |
import zio.metrics.Metric | |
import java.util.concurrent.TimeUnit | |
import zio.metrics.jvm.DefaultJvmMetrics | |
import io.opentelemetry.sdk.logs.`export`.SimpleLogRecordProcessor | |
import io.opentelemetry.sdk.logs.`export`.BatchLogRecordProcessor | |
import io.opentelemetry.sdk.logs.SdkLoggerProvider | |
import zio.logging.slf4j.bridge.Slf4jBridge | |
object Main extends ZIOAppDefault: | |
override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] = | |
// metrics | |
val meterProvider: RIO[Scope, SdkMeterProvider] = | |
val metricExporter: RIO[Scope, OtlpGrpcMetricExporter] = | |
ZIO.fromAutoCloseable: | |
ZIO.attempt: | |
OtlpGrpcMetricExporter.builder().setEndpoint("http://localhost:4317").build() | |
metricExporter | |
.flatMap: exporter => | |
ZIO | |
.fromAutoCloseable: | |
ZIO.attempt: | |
PeriodicMetricReader | |
.builder(exporter) | |
.setInterval(5, TimeUnit.SECONDS) | |
.build() | |
.map: meterReader => | |
SdkMeterProvider | |
.builder() | |
.setResource( | |
OltpResource | |
.builder() | |
.put("service.name", "zio-telemetry-playground") | |
.put("job", "zio-telemetry-playground") | |
.build() | |
) | |
.registerMetricReader(meterReader) | |
.build() | |
// logging | |
val loggerProvider: RIO[Scope, SdkLoggerProvider] = | |
val logExporter = | |
ZIO.fromAutoCloseable: | |
ZIO.attempt: | |
OtlpGrpcLogRecordExporter | |
.builder() | |
.setEndpoint("http://localhost:4317") | |
.setCompression("gzip") | |
.build() | |
logExporter | |
.flatMap: exporter => | |
ZIO.fromAutoCloseable: | |
ZIO.attempt: | |
BatchLogRecordProcessor | |
.builder(exporter) | |
.setMaxExportBatchSize(100) | |
.build() | |
.flatMap: processor => | |
ZIO.fromAutoCloseable: | |
ZIO.attempt: | |
SdkLoggerProvider | |
.builder() | |
.setResource( | |
OltpResource | |
.builder() | |
.put("service.name", "zio-telemetry-playground") | |
.put("job", "zio-telemetry-playground") | |
.build() | |
) | |
.addLogRecordProcessor(processor) | |
.build() | |
val otelSdkLayer: TaskLayer[OpenTelemetrySdk] = | |
ZLayer.scoped: | |
for | |
meterProvider <- meterProvider | |
loggerProvider <- loggerProvider | |
otelSdk <- ZIO.fromAutoCloseable: | |
ZIO.attempt: | |
OpenTelemetrySdk | |
.builder() | |
.setMeterProvider(meterProvider) | |
.setLoggerProvider(loggerProvider) | |
.build() | |
yield otelSdk | |
Runtime.removeDefaultLoggers >>> | |
Slf4jBridge.initialize >>> // route all SLF4J logs to ZIO RTS | |
otelSdkLayer >+> | |
OpenTelemetry.contextZIO >+> | |
OpenTelemetry.metrics("zio-telemetry-playground", None, None) >+> | |
OpenTelemetry.logging("zio-telemetry-playground", logLevel = LogLevel.Debug) >+> // log all ZIO logs to OTLP | |
OpenTelemetry.zioMetrics >>> // ship all metrics to OTLP | |
DefaultJvmMetrics.live.unit | |
override def run = | |
val metric: Metric.Counter[Any] = | |
Metric | |
.counter("test_cal") | |
.contramap[Any](_ => 1L) | |
(ZIO.logInfo("Hello from cal!") | |
@@ ZIOAspect.annotated( | |
"bim" -> "boom", | |
"bim2" -> "boom2", | |
"bim3" -> "boom3" | |
) | |
@@ metric).repeat(Schedule.spaced(1.second)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
An example using zio-telemetry + ZIO showing how to do:
Main.scala