From 51ed4e8d628fafeda128fd352c186b2606b00ad3 Mon Sep 17 00:00:00 2001 From: Maksym Ochenashko Date: Sun, 3 Mar 2024 21:30:31 +0200 Subject: [PATCH] site: add SDK section --- README.md | 13 ++-- build.sbt | 8 ++- docs/directory.conf | 11 ++++ docs/index.md | 13 ++-- docs/sdk/configuration.md | 133 ++++++++++++++++++++++++++++++++++++++ docs/sdk/directory.conf | 6 ++ docs/sdk/overview.md | 90 ++++++++++++++++++++++++++ 7 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 docs/directory.conf create mode 100644 docs/sdk/configuration.md create mode 100644 docs/sdk/directory.conf create mode 100644 docs/sdk/overview.md diff --git a/README.md b/README.md index 934a20c2b..2fc811e83 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ Specification][otel spec] atop [Cats Effect][cats-effect]. no-op implementations. These are appropriate for library instrumentation. +* SDK modules provide working telemetry (only tracing, currently) for applications. + SDK modules are implemented in Scala from scratch. Available for JVM, Scala.js, and Scala Native. + The implementation remains **experimental** and some functionality may be lacking. + * [opentelemetry-java][opentelemetry-java] backend provided for the JVM. This provides working telemetry for applications. @@ -29,10 +33,11 @@ it out and let us know what you think. ## Modules availability -| Module / Platform | JVM | Scala Native | Scala.js | -|:-----------------:|:---:|:------------:|:--------:| -| `otel4s-core` | ✅ | ✅ | ✅ | -| `otel4s-oteljava` | ✅ | ❌ | ❌ | +| Module / Platform | JVM | Scala Native | Scala.js | +|:---------------------------:|:---:|:------------:|:--------:| +| `otel4s-core` | ✅ | ✅ | ✅ | +| `otel4s-sdk` (tracing only) | ✅ | ✅ | ✅ | +| `otel4s-oteljava` | ✅ | ❌ | ❌ | ## Learn more diff --git a/build.sbt b/build.sbt index 208ab9445..db11616db 100644 --- a/build.sbt +++ b/build.sbt @@ -546,7 +546,7 @@ lazy val examples = project lazy val docs = project .in(file("site")) .enablePlugins(TypelevelSitePlugin) - .dependsOn(oteljava) + .dependsOn(oteljava, sdk.jvm, `sdk-exporter`.jvm) .settings( libraryDependencies ++= Seq( "org.apache.pekko" %% "pekko-http" % PekkoHttpVersion, @@ -565,6 +565,12 @@ lazy val docs = project "build-tool", ChoiceConfig("sbt", "sbt"), ChoiceConfig("scala-cli", "Scala CLI") + ).withSeparateEbooks, + SelectionConfig( + "sdk-options-source", + ChoiceConfig("sbt", "sbt"), + ChoiceConfig("scala-cli", "Scala CLI"), + ChoiceConfig("shell", "Shell") ).withSeparateEbooks ) ) diff --git a/docs/directory.conf b/docs/directory.conf new file mode 100644 index 000000000..95b09b5dc --- /dev/null +++ b/docs/directory.conf @@ -0,0 +1,11 @@ +laika.title = Examples + +laika.navigationOrder = [ + index.md + modules-structure.md + tracing-context-propagation.md + instrumentation + customization + sdk + examples +] diff --git a/docs/index.md b/docs/index.md index 3857779b3..241a74d74 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,6 +14,10 @@ Specification][otel spec] atop [Cats Effect][cats-effect]. no-op implementations. These are appropriate for library instrumentation. +* SDK modules provide working telemetry (only tracing, currently) for applications. + SDK modules are implemented in Scala from scratch. Available for JVM, Scala.js, and Scala Native. + The implementation remains **experimental** and some functionality may be lacking. + * [opentelemetry-java][opentelemetry-java] backend provided for the JVM. This provides working telemetry for applications. @@ -26,10 +30,11 @@ it out and let us know what you think. ## Modules availability -| Module / Platform | JVM | Scala Native | Scala.js | -|:-----------------:|:---:|:------------:|:--------:| -| `otel4s-core` | ✅ | ✅ | ✅ | -| `otel4s-oteljava` | ✅ | ❌ | ❌ | +| Module / Platform | JVM | Scala Native | Scala.js | +|:---------------------------:|:---:|:------------:|:--------:| +| `otel4s-core` | ✅ | ✅ | ✅ | +| `otel4s-sdk` (tracing only) | ✅ | ✅ | ✅ | +| `otel4s-oteljava` | ✅ | ❌ | ❌ | ## Getting started diff --git a/docs/sdk/configuration.md b/docs/sdk/configuration.md new file mode 100644 index 000000000..95d81fa89 --- /dev/null +++ b/docs/sdk/configuration.md @@ -0,0 +1,133 @@ +# Configuration + +The `OpenTelemetrySdk.autoConfigured(...)` and `SdkTraces.autoConfigured(...)` rely on the environment variables and system properties to configure the SDK. + +There are several ways to configure the options: + +@:select(sdk-options-source) + +@:choice(sbt) + +Add settings to the `build.sbt`: + +```scala +javaOptions += "-Dotel.service.name=auth-service" +envVars ++= Map("OTEL_SERVICE_NAME" -> "auth-service") +``` + +@:choice(scala-cli) + +Add directives to the `*.scala` file: + +```scala +//> using javaOpt -Dotel.service.name=auth-service +``` + +@:choice(shell) + +```shell +$ export OTEL_SERVICE_NAME=auth-service +``` +@:@ + +## Common + +| System property | Environment variable | Description | +|-------------------|-----------------------|-----------------------------------------------------------| +| otel.sdk.disabled | OTEL\\_SDK\\_DISABLED | If true returns a no-op SDK instance. Default is `false`. | + + +## Telemetry resource + +It's highly recommended to specify the `service.name` for your application. +For example, `auth-service` could be an application that handles authentication requests, +and `jobs-dispatcher` could be an application that processes background jobs. + +If not specified, SDK defaults the service name to `unknown_service:scala`. + +| System property | Environment variable | Description | +|------------------------------------------|--------------------------------------------------|-------------------------------------------------------------------------------------------------------------| +| otel.resource.attributes | OTEL\\_RESOURCE\\_ATTRIBUTES | Specify resource attributes in the following format: `key1=val1,key2=val2,key3=val3`. | +| otel.service.name | OTEL\\_SERVICE\\_NAME | Specify logical service name. Takes precedence over `service.name` defined with `otel.resource.attributes`. | +| otel.experimental.resource.disabled-keys | OTEL\\_EXPERIMENTAL\\_RESOURCE\\_DISABLED\\_KEYS | Specify resource attribute keys that are filtered. | + +## Tracing + +### Exporters + +| System property | Environment variable | Description | +|----------------------|--------------------------|------------------------------------------------------------------------------------------------------------------------| +| otel.traces.exporter | OTEL\\_TRACES\\_EXPORTER | List of exporters to be export spans, separated by commas. `none` means no autoconfigured exporter. Default is `otlp`. | + + +Options supported out of the box: + +- `otlp` - requires `otel4s-sdk-exporter` dependency. +- `logging` - prints the name of the span along with its attributes to stdout. It's mainly used for testing and debugging. +- `none` - means no autoconfigured exporter. + +### OTLP exporter + +The exporter can be configured by two sets of settings: +- global: `otel.expoter.otlp.{x}` +- target-specific: `otel.exporter.otlp.traces.{x}` + +Global properties can be used to configure tracer and metric exporters simultaneously. +Global `otel.exporter.otlp.endpoint` must be a **base** URL. The configurer automatically adds path (i.e. `v1/traces`) to the URL. + +Target-specific properties are prioritized. E.g. `otel.exporter.otlp.traces.endpoint` is prioritized over `otel.exporter.otlp.endpoint`. + +| System property | Environment variable | Description | +|---------------------------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| otel.exporter.otlp.endpoint | OTEL\\_EXPORTER\\_OTLP\\_ENDPOINT | The OTLP traces, metrics, and logs endpoint to connect to. Must be a **base** URL with a scheme of either http or https based on the use of TLS. Default is `http://localhost:4318/`. | +| otel.exporter.otlp.headers | OTEL\\_EXPORTER\\_OTLP\\_HEADERS | Key-value pairs separated by commas to pass as request headers on OTLP trace, metric, and log requests. | +| otel.exporter.otlp.compression | OTEL\\_EXPORTER\\_OTLP\\_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include gzip. By default, no compression will be used. | +| otel.exporter.otlp.timeout | OTEL\\_EXPORTER\\_OTLP\\_TIMEOUT | The maximum waiting time to send each OTLP trace, metric, and log batch. Default is `10 seconds`. | +| **Target specific:** | | | +| otel.exporter.otlp.traces.endpoint | OTEL\\_EXPORTER\\_OTLP\\_TRACES\\_ENDPOINT | The OTLP traces endpoint to connect to. Default is `http://localhost:4318/v1/traces`. | +| otel.exporter.otlp.traces.headers | OTEL\\_EXPORTER\\_OTLP\\_TRACES\\_HEADERS | Key-value pairs separated by commas to pass as request headers on OTLP trace requests. | +| otel.exporter.otlp.traces.compression | OTEL\\_EXPORTER\\_OTLP\\_TRACES\\_COMPRESSION | The compression type to use on OTLP trace requests. Options include gzip. By default, no compression will be used. | +| otel.exporter.otlp.traces.timeout | OTEL\\_EXPORTER\\_OTLP\\_TRACES\\_TIMEOUT | The maximum waiting time to send each OTLP trace batch. Default is `10 seconds`. | + +### Propagators + +The propagators determine which distributed tracing header formats are used, and which baggage propagation header formats are used. + +| System property | Environment variable | Description | +|------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------| +| otel.propagators | OTEL\\_PROPAGATORS | The propagators to use. Use a comma-separated list for multiple propagators. Default is `tracecontext,baggage` (W3C). | + +Options supported out of the box: +- `tracecontext` - [W3C Trace Context](https://www.w3.org/TR/trace-context/) +- `baggage` - [W3C Baggage](https://www.w3.org/TR/baggage/) +- `b3` - [B3 Single](https://github.com/openzipkin/b3-propagation#single-header) +- `b3multi` - [B3 Multi](https://github.com/openzipkin/b3-propagation#multiple-headers) +- `jaeger` - [Jaeger](https://www.jaegertracing.io/docs/1.21/client-libraries/#propagation-format) + +### Batch span processor + +| System property | Environment variable | Description | +|--------------------------------|------------------------------------------|-----------------------------------------------------------------------| +| otel.bsp.schedule.delay | OTEL\\_BSP\\_SCHEDULE\\_DELAY | The interval between two consecutive exports. Default is `5 seconds`. | +| otel.bsp.max.queue.size | OTEL\\_BSP\\_MAX\\_QUEUE_SIZE | The maximum queue size. Default is `2048`. | +| otel.bsp.max.export.batch.size | OTEL\\_BSP\\_MAX\\_EXPORT\\_BATCH\\_SIZE | The maximum batch size. Default is `512`. | +| otel.bsp.export.timeout | OTEL\\_BSP\\_EXPORT\\_TIMEOUT | The maximum allowed time to export data. Default is `30 seconds`. | + +### Sampler + +The sampler decides whether spans will be recorded. + +| System property | Environment variable | Description | +|-------------------------|-------------------------------|--------------------------------------------------------------------------| +| otel.traces.sampler | OTEL\\_TRACES\\_SAMPLER | The sampler to use for tracing. Defaults to `parentbased_always_on`. | +| otel.traces.sampler.arg | OTEL\\_TRACES\\_SAMPLER\\_ARG | An argument to the configured tracer if supported, for example, a ratio. | + + +The following options for `otel.traces.sampler` are supported out of the box: +- `always_on` - always samples spans, regardless of the parent span's sampling decision. +- `always_off` - never samples spans, regardless of the parent span's sampling decision. +- `traceidratio`, where `otel.traces.sampler.arg` sets the ratio - samples probabilistically based on the configured rate. +- `parentbased_always_on` - respects its parent span's sampling decision, but otherwise always samples. +- `parentbased_always_off` - respects its parent span's sampling decision, but otherwise never samples. +- `parentbased_traceidratio`, where `otel.traces.sampler.arg` sets the ratio - respects its parent span's sampling decision, +but otherwise samples probabilistically based on the configured rate. diff --git a/docs/sdk/directory.conf b/docs/sdk/directory.conf new file mode 100644 index 000000000..35a9aefd7 --- /dev/null +++ b/docs/sdk/directory.conf @@ -0,0 +1,6 @@ +laika.title = SDK + +laika.navigationOrder = [ + overview.md + configuration.md +] diff --git a/docs/sdk/overview.md b/docs/sdk/overview.md new file mode 100644 index 000000000..3c168e83a --- /dev/null +++ b/docs/sdk/overview.md @@ -0,0 +1,90 @@ +# Overview + +SDK modules are implemented in Scala and available for all platforms: JVM, Scala Native, and Scala.js. +Currently, only **tracing** module is implemented. +The implementation remains **experimental** and some functionality may be lacking. + +## Getting Started + +@:select(build-tool) + +@:choice(sbt) + +Add settings to the `build.sbt`: + +```scala +libraryDependencies ++= Seq( + "org.typelevel" %%% "otel4s-sdk" % "@VERSION@", // <1> + "org.typelevel" %%% "otel4s-sdk-exporter" % "@VERSION@" // <2> +) +``` + +@:choice(scala-cli) + +Add directives to the `*.scala` file: + +```scala +//> using lib "org.typelevel::otel4s-sdk::@VERSION@" // <1> +//> using lib "org.typelevel::otel4s-sdk-exporter::@VERSION@" // <2> +``` + +@:@ + +1. Add the `otel4s-sdk` library +2. Add the `otel4s-sdk-exporter` library. Without the exporter, the application will crash + +_______ + +Then use `OpenTelemetrySdk.autoConfigured` or `SdkTraces.autoConfigured` to autoconfigure the SDK: +```scala mdoc:silent:reset +import cats.effect.{IO, IOApp} +import org.typelevel.otel4s.sdk.OpenTelemetrySdk +import org.typelevel.otel4s.sdk.exporter.otlp.trace.autoconfigure.OtlpSpanExporterAutoConfigure +import org.typelevel.otel4s.trace.TracerProvider + +object TelemetryApp extends IOApp.Simple { + + def run: IO[Unit] = + OpenTelemetrySdk + .autoConfigured[IO]( + _.addSpanExporterConfigurer( + OtlpSpanExporterAutoConfigure[IO] + ) // register OTLP exporter configurer + ) + .use { autoConfigured => + val sdk = autoConfigured.sdk + program(sdk.tracerProvider) + } + + def program(tracerProvider: TracerProvider[IO]): IO[Unit] = + ??? +} +``` + +## Configuration + +The `.autoConfigured(...)` relies on the environment variables and system properties to configure the SDK. +For example, use `export OTEL_SERVICE_NAME=auth-service` to configure the name of the service. + +See the full set of the [supported options](configuration.md). + +## Limitations + +### No autoload of third-party components + +Since Scala Native and Scala.js lack [SPI](https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html) support, +third-party components cannot be loaded dynamically as OpenTelemetry Java does. + +Hence, the configurers must be registered manually: +```scala mdoc:silent +OpenTelemetrySdk.autoConfigured[IO]( + _.addSpanExporterConfigurer(OtlpSpanExporterAutoConfigure[IO]) +) +``` + +### No environment-aware Telemetry Resource + +OpenTelemetry Java can detect a large variety of environments (e.g. GCP, AWS ECS, etc) and add additional +environment-specific attributes to the Telemetry Resource. + +Otel4s SDK module does not support this yet. But we have a plan to provide this functionality in the future.