Skip to content

Commit

Permalink
Add example for logback appender in instrumentation example
Browse files Browse the repository at this point in the history
  • Loading branch information
grouzen committed Nov 16, 2023
1 parent d1f2dcc commit d392caa
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 44 deletions.
3 changes: 1 addition & 2 deletions docs/opentelemetry-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ docker run --rm -it \
jaegertracing/all-in-one:1.47
```

To run Seq, you also need to specify an admin password:
To run Seq, you also need to specify an admin password (user is `admin`):
```bash
PH=$(echo 'admin123' | docker run --rm -i datalust/seq config hash)

docker run \
--name seq \
-d \
--restart unless-stopped \
-e ACCEPT_EULA=Y \
Expand Down
35 changes: 29 additions & 6 deletions docs/opentelemetry-instrumentation-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,49 @@ title: "OpenTelemetry Automatic Instrumentation Example"

You can find the source code [here](https://github.com/zio/zio-telemetry/tree/series/2.x/opentelemetry-instrumentation-example).

Firstly, download OpenTelemetry JVM agent JAR:
```bash
OTEL_AGENT_PATH=$(cs fetch --classpath "io.opentelemetry.javaagent:opentelemetry-javaagent:latest.release")
```
Firstly, we need to start the observability backends ([Jaeger](https://www.jaegertracing.io/) and [Seq](https://datalust.co/seq))

Then start Jaeger by running the following command:
Start Jaeger by running the following command:
```bash
docker run --rm -it \
-d \
-e COLLECTOR_OTLP_ENABLED=true \
-p 14250:14250 \
-p 16686:16686 \
-p 4317:4317 \
jaegertracing/all-in-one:1.47
```

To run Seq, you also need to specify an admin password (user is `admin`):
```bash
PH=$(echo 'admin123' | docker run --rm -i datalust/seq config hash)

docker run \
-d \
--restart unless-stopped \
-e ACCEPT_EULA=Y \
-e SEQ_FIRSTRUN_ADMINPASSWORDHASH="$PH" \
-p 80:80 \
-p 5341:5341 \
datalust/seq
```

After this, we can kick off our application to generate some metrics.

For this, we have to download OpenTelemetry JVM agent JAR:
```bash
OTEL_AGENT_PATH=$(cs fetch --classpath "io.opentelemetry.javaagent:opentelemetry-javaagent:latest.release")
```

Then start the server application
```bash
sbt -J-javaagent:$OTEL_AGENT_PATH \
-J-Dotel.service.name=example-server \
-J-Dotel.traces.sampler=always_on \
-J-Dotel.traces.exporter=otlp \
-J-Dotel.logs.exporter=otlp \
-J-Dotel.exporter.otlp.logs.protocol="http/protobuf" \
-J-Dotel.exporter.otlp.logs.endpoint="http://localhost:5341/ingest/otlp/v1/logs" \
-J-Dotel.metrics.exporter=none \
"opentelemetryInstrumentationExample/runMain zio.telemetry.opentelemetry.instrumentation.example.ServerApp"
```
Expand All @@ -40,4 +62,5 @@ sbt -J-javaagent:$OTEL_AGENT_PATH \
"opentelemetryInstrumentationExample/runMain zio.telemetry.opentelemetry.instrumentation.example.ClientApp"
```

Head over to [http://localhost:16686/](http://localhost:16686/) to see the result.
Head over to [Jaeger UI](http://localhost:16686/) and [Seq UI](http://localhost:80/) to see the result.

Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import io.opentelemetry.sdk.trace.SdkTracerProvider
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes
import zio._
import zio.telemetry.opentelemetry.example.config.AppConfig

/**
* https://www.jaegertracing.io/
*/
object JaegerTracer {

def live(resourceName: String, instrumentationScopeName: String): RLayer[AppConfig, Tracer] =
def live(resourceName: String, instrumentationScopeName: String): TaskLayer[Tracer] =
ZLayer(
for {
spanExporter <- ZIO.attempt(OtlpGrpcSpanExporter.builder().build())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="OpenTelemetry"
class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender">
</appender>

<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="OpenTelemetry"/>
</root>

</configuration>
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package zio.telemetry.opentelemetry.instrumentation.example

import io.opentelemetry.api.GlobalOpenTelemetry
import io.opentelemetry.api.{GlobalOpenTelemetry, OpenTelemetry}
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender
import zio.logging.backend.SLF4J
import zio._
import zio.config.ReadError
import zio.config.typesafe.TypesafeConfig
Expand All @@ -13,24 +15,36 @@ import zio.telemetry.opentelemetry.tracing.Tracing

object ServerApp extends ZIOAppDefault {

override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] =
Runtime.removeDefaultLoggers >>> SLF4J.slf4j

private val instrumentationScopeName = "zio.telemetry.opentelemetry.instrumentation.example.ServerApp"

private val configLayer: Layer[ReadError[String], AppConfig] =
TypesafeConfig.fromResourcePath(descriptor[AppConfig])

private val globalTracerLayer: TaskLayer[Tracer] =
ZLayer.fromZIO(
ZIO.attempt(GlobalOpenTelemetry.getTracer("zio.telemetry.opentelemetry.instrumentation.example.ServerApp"))
ZIO.attempt(GlobalOpenTelemetry.getTracer(instrumentationScopeName))
)

private val globalOpenTelemetry: TaskLayer[OpenTelemetry] =
ZLayer(ZIO.attempt(GlobalOpenTelemetry.get()))

override def run: Task[ExitCode] =
ZIO
.serviceWithZIO[HttpServer](_.start.exitCode)
.provide(
configLayer,
HttpServer.live,
HttpServerApp.live,
Tracing.live,
globalTracerLayer,
ContextStorage.native
)
(for {
server <- ZIO.service[HttpServer]
openTelemetry <- ZIO.service[OpenTelemetry]
_ <- ZIO.attempt(OpenTelemetryAppender.install(openTelemetry))
exitCode <- server.start.exitCode
} yield exitCode).provide(
configLayer,
HttpServer.live,
HttpServerApp.live,
Tracing.live,
ContextStorage.native,
globalTracerLayer,
globalOpenTelemetry
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package zio.telemetry.opentelemetry.instrumentation.example.http

import zio._
import zio.http._
import zio.Console.printLine
import zio.telemetry.opentelemetry.instrumentation.example.config.AppConfig

case class HttpServer(config: AppConfig, httpServerApp: HttpServerApp) {

def start: ZIO[Any, Throwable, Nothing] =
printLine(s"Starting HttpServer on port ${config.server.port}") *>
ZIO.logInfo(s"Starting HttpServer on port ${config.server.port}") *>
Server.serve(httpServerApp.routes).provide(Server.defaultWithPort(config.server.port))

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ case class HttpServerApp(tracing: Tracing) {
for {
_ <- tracing.addEvent("executing health logic")
_ <- tracing.setAttribute("zio", "telemetry")
_ <- ZIO.logInfo("health processing finished on the server")
response <- ZIO.succeed(Response.ok)
} yield response

Expand Down
52 changes: 32 additions & 20 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,32 @@ object Dependencies {
}

object Orgs {
val zio = "dev.zio"
val opentracing = "io.opentracing"
val opentelemetry = "io.opentelemetry"
val opencensus = "io.opencensus"
val jaegertracing = "io.jaegertracing"
val scalaLangModules = "org.scala-lang.modules"
val typelevel = "org.typelevel"
val softwaremillSttpClient3 = "com.softwaremill.sttp.client3"
val slf4j = "org.slf4j"
val grpc = "io.grpc"
val zio = "dev.zio"
val opentracing = "io.opentracing"
val opentelemetry = "io.opentelemetry"
val opentelemetryInstrumentation = "io.opentelemetry.instrumentation"
val opencensus = "io.opencensus"
val jaegertracing = "io.jaegertracing"
val scalaLangModules = "org.scala-lang.modules"
val typelevel = "org.typelevel"
val softwaremillSttpClient3 = "com.softwaremill.sttp.client3"
val slf4j = "org.slf4j"
val grpc = "io.grpc"
val logback = "ch.qos.logback"
}

private object ExampleVersions {
val cats = "2.7.0"
val grpcNetty = "1.47.0"
val jaeger = "1.8.0"
val slf4j = "1.7.36"
val sttp3 = "3.7.0"
val zipkin = "2.16.3"
val zioJson = "0.3.0-RC10"
val zioConfig = "3.0.1"
val zioHttp = "3.0.0-RC2"
val cats = "2.7.0"
val grpcNetty = "1.47.0"
val jaeger = "1.8.0"
val slf4j = "1.7.36"
val sttp3 = "3.7.0"
val zipkin = "2.16.3"
val zioJson = "0.3.0-RC10"
val zioConfig = "3.0.1"
val zioHttp = "3.0.0-RC2"
val zioLogging = "2.1.15"
val logback = "1.4.11"
}

lazy val zio = Seq(
Expand Down Expand Up @@ -88,7 +92,15 @@ object Dependencies {
)

lazy val opentelemetryInstrumentationExample = example ++ Seq(
Orgs.zio %% "zio-http" % ExampleVersions.zioHttp
Orgs.opentelemetry % "opentelemetry-exporter-otlp" % Versions.opentelemetry,
Orgs.opentelemetry % "opentelemetry-sdk" % Versions.opentelemetry,
Orgs.grpc % "grpc-netty-shaded" % ExampleVersions.grpcNetty,
Orgs.opentelemetryInstrumentation % "opentelemetry-logback-appender-1.0" % s"${Versions.opentelemetry}-alpha",
Orgs.zio %% "zio-http" % ExampleVersions.zioHttp,
Orgs.zio %% "zio-logging" % ExampleVersions.zioLogging,
Orgs.zio %% "zio-logging-slf4j2" % ExampleVersions.zioLogging,
Orgs.logback % "logback-classic" % ExampleVersions.logback,
Orgs.logback % "logback-core" % ExampleVersions.logback
)

}

0 comments on commit d392caa

Please sign in to comment.