Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

site: add SDK section #533

Merged
merged 1 commit into from
Mar 14, 2024
Merged
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
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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

Expand Down
8 changes: 7 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
)
)
Expand Down
11 changes: 11 additions & 0 deletions docs/directory.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
laika.title = Examples

laika.navigationOrder = [
index.md
modules-structure.md
tracing-context-propagation.md
instrumentation
customization
sdk
examples
]
13 changes: 9 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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

Expand Down
133 changes: 133 additions & 0 deletions docs/sdk/configuration.md
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 6 additions & 0 deletions docs/sdk/directory.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
laika.title = SDK

laika.navigationOrder = [
overview.md
configuration.md
]
90 changes: 90 additions & 0 deletions docs/sdk/overview.md
Original file line number Diff line number Diff line change
@@ -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.