Normalize tabpane shortcode use (#3137)

This commit is contained in:
Patrice Chalin 2023-08-07 13:37:08 -04:00 committed by GitHub
parent 6094eda3f7
commit 526347d242
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1196 additions and 1153 deletions

View File

@ -36,10 +36,9 @@ export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.example.com:4318
The collector serving at `collector.example.com:4318` would then be configured
like so:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=yaml >}}
{{< tab Traces >}}
{{< tabpane text=true >}} {{% tab Traces %}}
```yaml
receivers:
otlp: # the OTLP receiver the app is sending traces to
protocols:
@ -50,7 +49,7 @@ processors:
exporters:
jaeger: # the Jaeger exporter, to ingest traces to backend
endpoint: "https://jaeger.example.com:14250"
endpoint: https://jaeger.example.com:14250
tls:
insecure: true
@ -60,8 +59,11 @@ service:
receivers: [otlp]
processors: [batch]
exporters: [jaeger]
{{< /tab >}}
{{< tab Metrics >}}
```
{{% /tab %}} {{% tab Metrics %}}
```yaml
receivers:
otlp: # the OTLP receiver the app is sending metrics to
protocols:
@ -72,7 +74,7 @@ processors:
exporters:
prometheusremotewrite: # the PRW exporter, to ingest metrics to backend
endpoint: "https://prw.example.com/v1/api/remote_write"
endpoint: https://prw.example.com/v1/api/remote_write
service:
pipelines:
@ -80,9 +82,11 @@ service:
receivers: [otlp]
processors: [batch]
exporters: [prometheusremotewrite]
```
{{< /tab >}}
{{< tab Logs >}}
{{% /tab %}} {{% tab Logs %}}
```yaml
receivers:
otlp: # the OTLP receiver the app is sending logs to
protocols:
@ -93,7 +97,7 @@ processors:
exporters:
file: # the File Exporter, to ingest logs to local file
path: "./app42_example.log"
path: ./app42_example.log
rotation:
service:
@ -102,10 +106,9 @@ service:
receivers: [otlp]
processors: [batch]
exporters: [file]
{{< /tab >}}
{{< /tabpane>}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
```
{{% /tab %}} {{< /tabpane >}}
If you want to try it out for yourself, you can have a look at the end-to-end
[Java][java-otlp-example] or [Python][py-otlp-example] examples.

View File

@ -111,10 +111,9 @@ configuration fields:
The first-tier collector servicing the OTLP endpoint would be configured as
shown below:
<!-- prettier-ignore-start -->
{{< tabpane text=true >}} {{% tab Static %}}
{{< tabpane lang=yaml >}}
{{< tab Static >}}
```yaml
receivers:
otlp:
protocols:
@ -138,8 +137,11 @@ service:
traces:
receivers: [otlp]
exporters: [loadbalancing]
{{< /tab >}}
{{< tab DNS >}}
```
{{% /tab %}} {{% tab DNS %}}
```yaml
receivers:
otlp:
protocols:
@ -159,8 +161,11 @@ service:
traces:
receivers: [otlp]
exporters: [loadbalancing]
{{< /tab >}}
{{< tab "DNS with service" >}}
```
{{% /tab %}} {{% tab "DNS with service" %}}
```yaml
receivers:
otlp:
protocols:
@ -168,7 +173,7 @@ receivers:
exporters:
loadbalancing:
routing_key: "service"
routing_key: service
protocol:
otlp:
insecure: true
@ -182,10 +187,9 @@ service:
traces:
receivers: [otlp]
exporters: [loadbalancing]
{{< /tab >}}
{{< /tabpane>}}
```
<!-- prettier-ignore-end -->
{{% /tab %}} {{< /tabpane >}}
The load-balancing exporter emits metrics including
`otelcol_loadbalancer_num_backends` and `otelcol_loadbalancer_backend_latency`

View File

@ -29,7 +29,7 @@ Pull a docker image and run the collector in a container. Replace
`{{% param collectorVersion %}}` with the version of the Collector you wish to
run.
{{% tabpane text=true %}} {{% tab DockerHub %}}
{{< tabpane text=true >}} {{% tab DockerHub %}}
```sh
docker pull otel/opentelemetry-collector-contrib:{{% param collectorVersion %}}
@ -43,12 +43,12 @@ docker pull ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetr
docker run ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:{{% param collectorVersion %}}
```
{{% /tab %}} {{% /tabpane %}}
{{% /tab %}} {{< /tabpane >}}
To load your custom configuration `config.yaml` from your current working
directory, mount that file as a volume:
{{% tabpane text=true %}} {{% tab DockerHub %}}
{{< tabpane text=true >}} {{% tab DockerHub %}}
```sh
docker run -v $(pwd)/config.yaml:/etc/otelcol-contrib/config.yaml otel/opentelemetry-collector-contrib:{{% param collectorVersion %}}
@ -60,7 +60,7 @@ docker run -v $(pwd)/config.yaml:/etc/otelcol-contrib/config.yaml otel/opentelem
docker run -v $(pwd)/config.yaml:/etc/otelcol-contrib/config.yaml ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:{{% param collectorVersion %}}
```
{{% /tab %}} {{% /tabpane %}}
{{% /tab %}} {{< /tabpane >}}
## Docker Compose
@ -118,32 +118,34 @@ To get started on alpine systems run the following replacing
`v{{% param collectorVersion %}}` with the version of the Collector you wish to
run.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tab AMD64 >}}
{{< tabpane text=true >}} {{% tab AMD64 %}}
```sh
apk update
apk add wget shadow
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_amd64.apk
apk add --allow-untrusted otelcol_{{% param collectorVersion %}}_linux_amd64.apk
{{< /tab >}}
```
{{< tab ARM64 >}}
{{% /tab %}} {{% tab ARM64 %}}
```sh
apk update
apk add wget shadow
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_arm64.apk
apk add --allow-untrusted otelcol_{{% param collectorVersion %}}_linux_arm64.apk
{{< /tab >}}
```
{{< tab i386 >}}
{{% /tab %}} {{% tab i386 %}}
```sh
apk update
apk add wget shadow
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_386.apk
apk add --allow-untrusted otelcol_{{% param collectorVersion %}}_linux_386.apk
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
```
{{% /tab %}} {{< /tabpane >}}
### DEB Installation
@ -151,32 +153,34 @@ To get started on Debian systems run the following replacing
`v{{% param collectorVersion %}}` with the version of the Collector you wish to
run and `amd64` with the appropriate architecture.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tab AMD64 >}}
{{< tabpane text=true >}} {{% tab AMD64 %}}
```sh
sudo apt-get update
sudo apt-get -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_amd64.deb
sudo dpkg -i otelcol_{{% param collectorVersion %}}_linux_amd64.deb
{{< /tab >}}
```
{{< tab ARM64 >}}
{{% /tab %}} {{% tab ARM64 %}}
```sh
sudo apt-get update
sudo apt-get -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_arm64.deb
sudo dpkg -i otelcol_{{% param collectorVersion %}}_linux_arm64.deb
{{< /tab >}}
```
{{< tab i386 >}}
{{% /tab %}} {{% tab i386 %}}
```sh
sudo apt-get update
sudo apt-get -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_386.deb
sudo dpkg -i otelcol_{{% param collectorVersion %}}_linux_386.deb
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
```
{{% /tab %}} {{< /tabpane >}}
### RPM Installation
@ -184,32 +188,34 @@ To get started on Red Hat systems run the following replacing
`v{{% param collectorVersion %}}` with the version of the Collector you wish to
run and `x86_64` with the appropriate architecture.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tab AMD64 >}}
{{< tabpane text=true >}} {{% tab AMD64 %}}
```sh
sudo yum update
sudo yum -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_amd64.rpm
sudo rpm -ivh otelcol_{{% param collectorVersion %}}_linux_amd64.rpm
{{< /tab >}}
```
{{< tab ARM64 >}}
{{% /tab %}} {{% tab ARM64 %}}
```sh
sudo yum update
sudo yum -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_arm64.rpm
sudo rpm -ivh otelcol_{{% param collectorVersion %}}_linux_arm64.rpm
{{< /tab >}}
```
{{< tab i386 >}}
{{% /tab %}} {{% tab i386 %}}
```sh
sudo yum update
sudo yum -y install wget systemctl
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_386.rpm
sudo rpm -ivh otelcol_{{% param collectorVersion %}}_linux_386.rpm
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
```
{{% /tab %}} {{< /tabpane >}}
### Manual Installation
@ -217,31 +223,35 @@ Linux [releases][] are available for various architectures. It's possible to
download the archive containing the binary and install it on your machine
manually:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tab AMD64 >}}
{{< tabpane text=true >}} {{% tab AMD64 %}}
```sh
curl --proto '=https' --tlsv1.2 -fOL https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_amd64.tar.gz
tar -xvf otelcol_{{% param collectorVersion %}}_linux_amd64.tar.gz
{{< /tab >}}
```
{{< tab ARM64 >}}
{{% /tab %}} {{% tab ARM64 %}}
```sh
curl --proto '=https' --tlsv1.2 -fOL https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_arm64.tar.gz
tar -xvf otelcol_{{% param collectorVersion %}}_linux_arm64.tar.gz
{{< /tab >}}
```
{{< tab i386 >}}
{{% /tab %}} {{% tab i386 %}}
```sh
curl --proto '=https' --tlsv1.2 -fOL https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_386.tar.gz
tar -xvf otelcol_{{% param collectorVersion %}}_linux_386.tar.gz
{{< /tab >}}
```
{{< tab ppc64le >}}
{{% /tab %}} {{% tab ppc64le %}}
```sh
curl --proto '=https' --tlsv1.2 -fOL https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_linux_ppc64le.tar.gz
tar -xvf otelcol_{{% param collectorVersion %}}_linux_ppc64le.tar.gz
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
```
{{% /tab %}} {{< /tabpane >}}
### Automatic Service Configuration
@ -272,21 +282,21 @@ MacOS [releases][] are available for Intel- & ARM-based systems. They are
packaged as gzipped tarballs (`.tar.gz`) and will need to be unpacked with a
tool that supports this compression format:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tab Intel >}}
{{< tabpane text=true >}} {{% tab Intel %}}
```sh
curl --proto '=https' --tlsv1.2 -fOL https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_darwin_amd64.tar.gz
tar -xvf otelcol_{{% param collectorVersion %}}_darwin_amd64.tar.gz
{{< /tab >}}
```
{{< tab ARM >}}
{{% /tab %}} {{% tab ARM %}}
```sh
curl --proto '=https' --tlsv1.2 -fOL https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{% param collectorVersion %}}/otelcol_{{% param collectorVersion %}}_darwin_arm64.tar.gz
tar -xvf otelcol_{{% param collectorVersion %}}_darwin_arm64.tar.gz
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
```
{{% /tab %}} {{< /tabpane >}}
Every Collector release includes an `otelcol` executable that you can run after
unpacking.

View File

@ -233,6 +233,6 @@ To determine if a Baggage item is set, you can leverage the `propagation` API to
parse the Baggage header, and leverage the `baggage` API to get or set entries.
```typescript
const baggage = propagation.getBaggage(context.active());
if (baggage?.getEntry("synthetic_request")?.value == "true") {...}
const baggage = propagation.getBaggage(context.active());
if (baggage?.getEntry("synthetic_request")?.value == "true") {...}
```

View File

@ -20,31 +20,33 @@ application (a HTTP server & HTTP client). For more details read
You can build OpenTelemetry C++ on Windows, macOS or Linux. First you need to
install some dependencies:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab "Linux (apt)" %}}
{{< tab "Linux (apt)" >}}
```sh
sudo apt-get install git cmake g++ libcurl4-openssl-dev
{{< /tab >}}
```
{{< tab "Linux (yum)" >}}
{{% /tab %}} {{% tab "Linux (yum)" %}}
```sh
sudo yum install git cmake g++ libcurl-devel
{{< /tab >}}
```
{{< tab "Linux (alpine)" >}}
{{% /tab %}} {{% tab "Linux (alpine)" %}}
```sh
sudo apk add git cmake g++ make curl-dev
{{< /tab >}}
```
{{< tab "MacOS (homebrew)" >}}
{{% /tab %}} {{% tab "MacOS (homebrew)" %}}
```sh
xcode-select —install
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install git cmake
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Building

View File

@ -28,17 +28,17 @@ Zipkin also run by [docker-compose](https://docs.docker.com/compose/).
To export to the running Collector the `opentelemetry_exporter` package must be
added to the project's dependencies:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
{deps, [{opentelemetry_api, "~> {{% param versions.otelApi %}}"},
{opentelemetry, "~> {{% param versions.otelSdk %}}"},
{opentelemetry_exporter, "~> {{% param versions.otelExporter %}}"}]}.
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
def deps do
[
{:opentelemetry_api, "~> {{% param versions.otelApi %}}"},
@ -46,11 +46,9 @@ def deps do
{:opentelemetry_exporter, "~> {{% param versions.otelExporter %}}"}
]
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
It should then be added to the configuration of the Release before the SDK
Application to ensure the exporter's dependencies are started before the SDK
@ -59,11 +57,9 @@ attempts to initialize and use the exporter.
Example of Release configuration in `rebar.config` and for
[mix's Release task](https://hexdocs.pm/mix/Mix.Tasks.Release.html):
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% rebar.config
{relx, [{release, {my_instrumented_release, "0.1.0"},
[opentelemetry_exporter,
@ -71,9 +67,11 @@ Example of Release configuration in `rebar.config` and for
my_instrumented_app]},
...]}.
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# mix.exs
def project do
[
@ -86,11 +84,9 @@ def project do
]
]
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Finally, the runtime configuration of the `opentelemetry` and
`opentelemetry_exporter` Applications are set to export to the Collector. The
@ -99,11 +95,9 @@ the HTTP protocol with endpoint of `localhost` on port `4318`. If using `grpc`
for the `otlp_protocol` the endpoint should be changed to
`http://localhost:4317`.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% config/sys.config.src
[
{opentelemetry,
@ -114,9 +108,11 @@ for the `otlp_protocol` the endpoint should be changed to
[{otlp_protocol, http_protobuf},
{otlp_endpoint, "http://localhost:4318"}]}]}
].
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# config/runtime.exs
config :opentelemetry,
span_processor: :batch,
@ -125,8 +121,6 @@ config :opentelemetry,
config :opentelemetry_exporter,
otlp_protocol: :http_protobuf,
otlp_endpoint: "http://localhost:4318"
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}

View File

@ -303,57 +303,51 @@ more telemetry backends.
To get started with this guide, create a new project with `rebar3` or `mix`:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
rebar3 new release otel_getting_started
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
mix new --sup otel_getting_started
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Then, in the project you just created, add both `opentelemetry_api` and
`opentelemetry` as dependencies. We add both because this is a project we will
run as a Release and export spans from.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
{deps, [{opentelemetry_api, "~> {{% param versions.otelApi %}}"},
{opentelemetry, "~> {{% param versions.otelSdk %}}"}]}.
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
def deps do
[
{:opentelemetry_api, "~> {{% param versions.otelApi %}}"},
{:opentelemetry, "~> {{% param versions.otelSdk %}}"}
]
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
In the case of Erlang, the API Application will also need to be added to
`src/otel_getting_started.app.src` and a `relx` section to `rebar.config`. In an
Elixir project, a `releases` section needs to be added to `mix.exs`:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% src/otel_getting_started.app.src
...
{applications, [kernel,
@ -367,9 +361,11 @@ Elixir project, a `releases` section needs to be added to `mix.exs`:
otel_getting_started]},
...]}.
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# mix.exs
releases: [
otel_getting_started: [
@ -377,11 +373,9 @@ releases: [
applications: [opentelemetry: :temporary, otel_getting_started: :permanent]
]
]
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
The SDK `opentelemetry` should be added as early as possible in the Release boot
process to ensure it is available before any telemetry is produced. Here it is
@ -418,40 +412,36 @@ To configure OpenTelemetry to use a particular exporter, in this case
the `exporter` for the span processor `otel_batch_processor`, a type of span
processor that batches up multiple spans over a period of time:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% config/sys.config.src
[
{opentelemetry,
[{span_processor, batch},
{traces_exporter, {otel_exporter_stdout, []}}]}
].
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# config/runtime.exs
config :opentelemetry,
span_processor: :batch,
traces_exporter: {:otel_exporter_stdout, []}
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Working with Spans
Now that the dependencies and configuration are set up, we can create a module
with a function `hello/0` that starts some spans:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% apps/otel_getting_started/src/otel_getting_started.erl
-module(otel_getting_started).
@ -473,9 +463,11 @@ nice_operation(_SpanCtx) ->
?set_attributes([{lemons_key, <<"five">>}]),
?add_event(<<"Sub span event!">>, [])
end).
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# lib/otel_getting_started.ex
defmodule OtelGettingStarted do
require OpenTelemetry.Tracer, as: Tracer
@ -492,11 +484,9 @@ defmodule OtelGettingStarted do
end
end
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
In this example, we're using macros that use the process dictionary for context
propagation and for getting the tracer.
@ -521,11 +511,9 @@ To test out this project and see the spans created, you can run with
`rebar3 shell` or `iex -S mix`, each will pick up the corresponding
configuration for the release, resulting in the tracer and exporter to started.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```console
$ rebar3 shell
===> Compiling otel_getting_started
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
@ -547,9 +535,11 @@ true
[{another_key,<<"yes">>}],
[{event,-576460750077877345,<<"Nice operation!">>,[{<<"bogons">>,100}]}],
[],undefined,1,false,undefined}
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```console
$ iex -S mix
Erlang/OTP 23 [erts-11.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]
@ -571,11 +561,9 @@ iex(2)>
[{another_key,<<"yes">>}],
[{event,-576460741349446725,<<"Nice operation!">>,[{<<"bogons">>,100}]}],
[],undefined,1,false,undefined}
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Next Steps

View File

@ -53,21 +53,19 @@ interactive shell, a `Tracer` with a blank name and version is used.
The created `Tracer`'s record can be looked up by the name of a module in the
OTP Application:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
opentelemetry:get_application_tracer(?MODULE)
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
:opentelemetry.get_application_tracer(__MODULE__)
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
This is how the Erlang and Elixir macros for starting and updating `Spans` get a
`Tracer` automatically without need for you to pass the variable in each call.
@ -77,19 +75,19 @@ This is how the Erlang and Elixir macros for starting and updating `Spans` get a
Now that you have [Tracer](/docs/concepts/signals/traces/#tracer)s initialized,
you can create [Spans](/docs/concepts/signals/traces/#spans).
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
?with_span(main, #{}, fun() ->
%% do work here.
%% when this function returns the Span ends
end).
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
require OpenTelemetry.Tracer
...
@ -98,23 +96,18 @@ OpenTelemetry.Tracer.with_span :main do
# do work here
# when the block ends the Span ends
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
<!-- markdownlint-disable heading-increment -->
{{% /tab %}} {{< /tabpane >}}
The above code sample shows how to create an active Span, which is the most
common kind of Span to create.
### Create Nested Spans
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
parent_function() ->
?with_span(parent, #{}, fun child_function/0).
@ -126,9 +119,11 @@ child_function() ->
%% do work here. when this function returns, child will complete.
end).
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
require OpenTelemetry.Tracer
def parent_function() do
@ -144,11 +139,9 @@ def child_function() do
## do work here. when this function returns, :child will complete.
end
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
### Spans in Separate Processes
@ -169,11 +162,9 @@ attaching the context and setting the new span as currently active in the
process. The whole context should be attached in order to not lose other
telemetry data like [baggage](/docs/specs/otel/baggage/api/).
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
SpanCtx = ?start_span(child),
Ctx = otel_ctx:get_current(),
@ -186,9 +177,11 @@ proc_lib:spawn_link(fun() ->
?end_span(SpanCtx)
end),
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
span_ctx = OpenTelemetry.Tracer.start_span(:child)
ctx = OpenTelemetry.Ctx.get_current()
@ -202,11 +195,9 @@ task = Task.async(fn ->
end)
_ = Task.await(task)
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
### Linking the New Span
@ -215,11 +206,9 @@ Span Links that causally link it to another Span. A
[Link](/docs/concepts/signals/traces/#span-links) needs a Span context to be
created.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
Parent = ?current_span_ctx,
proc_lib:spawn_link(fun() ->
%% a new process has a new context so the span created
@ -228,9 +217,11 @@ proc_lib:spawn_link(fun() ->
?with_span('other-process', #{links => [Link]},
fun() -> ok end)
end),
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
parent = OpenTelemetry.current_span_ctx()
task = Task.async(fn ->
# a new process has a new context so the span created
@ -240,11 +231,9 @@ task = Task.async(fn ->
:hello
end
end)
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
### Adding Attributes to a Span
@ -256,28 +245,26 @@ The following example shows the two ways of setting attributes on a span by both
setting an attribute in the start options and then again with `set_attributes`
in the body of the span operation:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
?with_span(my_span, #{attributes => [{'start-opts-attr', <<"start-opts-value">>}]},
fun() ->
?set_attributes([{'my-attribute', <<"my-value">>},
{another_attribute, <<"value-of-attribute">>}])
end)
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
Tracer.with_span :span_1, %{attributes: [{:"start-opts-attr", <<"start-opts-value">>}]} do
Tracer.set_attributes([{:"my-attributes", "my-value"},
{:another_attribute, "value-of-attributes"}])
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
### Semantic Attributes
@ -291,79 +278,73 @@ from the specification and provided in
For example, an instrumentation for an HTTP client or server would need to
include semantic attributes like the scheme of the URL:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
-include_lib("opentelemetry_semantic_conventions/include/trace.hrl").
?with_span(my_span, #{attributes => [{?HTTP_SCHEME, <<"https">>}]},
fun() ->
...
end)
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
alias OpenTelemetry.SemanticConventions.Trace, as: Trace
Tracer.with_span :span_1, %{attributes: [{Trace.http_scheme(), <<"https">>}]} do
end
{{< /tab >}}
```
{{< /tabpane >}}
{{% /tab %}} {{< /tabpane >}}
### Adding Events
A [Span
Event](/docs/concepts/signals/traces/#span-events) is a
human-readable message on an
[Span](/docs/concepts/signals/traces/#spans)
that represents a discrete event with no duration that can be tracked by a
single time stamp. You can think of it like a primitive log.
A [Span Event](/docs/concepts/signals/traces/#span-events) is a human-readable
message on an [Span](/docs/concepts/signals/traces/#spans) that represents a
discrete event with no duration that can be tracked by a single timestamp. You
can think of it like a primitive log.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
?add_event(<<"Gonna try it">>),
%% Do the thing
?add_event(<<"Did it!">>),
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
Tracer.add_event("Gonna try it")
%% Do the thing
Tracer.add_event("Did it!")
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Events can also have attributes of their own:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
?add_event(<<"Process exited with reason">>, [{pid, Pid)}, {reason, Reason}]))
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
Tracer.add_event("Process exited with reason", pid: pid, reason: Reason)
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
### Set Span Status
@ -375,23 +356,21 @@ could override the Error status with `StatusCode.OK`, but dont set
The status can be set at any time before the span is finished:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
-include_lib("opentelemetry_api/include/opentelemetry.hrl").
?set_status(?OTEL_STATUS_ERROR, <<"this is not ok">>)
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
Tracer.set_status(:error, "this is not ok")
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Metrics

View File

@ -26,28 +26,26 @@ propagators. By default the global propagators used are the W3C
These global propagators can be configured by the Application environment
variable `text_map_propagators`:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% sys.config
...
{text_map_propagators, [baggage,
trace_context]},
...
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
## runtime.exs
...
text_map_propagators: [:baggage, :trace_context],
...
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Or through a comma separated list with the environment variable
`OTEL_PROPAGATORS`. Both forms of configuration accept the values
@ -57,29 +55,27 @@ and `b3multi`.
To manually inject or extract context the `otel_propagator_text_map` module can
be used:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% uses the context from the process dictionary to add to an empty list of headers
Headers = otel_propagator_text_map:inject([]),
%% creates a context in the process dictionary from Headers
otel_propagator_text_map:extract(Headers),
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# uses the context from the process dictionary to add to an empty list of headers
headers = :otel_propagator_text_map.inject([])
# creates a context in the process dictionary from headers
:otel_propagator_text_map.extract(headers)
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
`otel_propagator_text_map:inject/1` and `otel_propagator_text_map:extract/1` use
globally registered propagators. To use a specific propagator

View File

@ -29,23 +29,21 @@ detectors use the OS environment variable `OTEL_RESOURCE_ATTRIBUTES` and the
The detectors to use is a list of module names and can be configured in the
Application configuration:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% sys.config
{resource_detectors, [otel_resource_env_var, otel_resource_app_env]}
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
## runtime.exs
resource_detectors: [:otel_resource_env_var, :otel_resource_app_env]
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Or through the environment variable `OTEL_RESOURCE_DETECTORS`:
@ -72,23 +70,21 @@ OTEL_RESOURCE_ATTRIBUTES="deployment.environment=development"
Alternatively, use the `resource` Application environment under the
`opentelemetry` Application configuration of `sys.config` or `runtime.exs`:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% sys.config
{resource, #{deployment => #{environment => <<"development">>}}
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
## runtime.exs
resource: %{deployment: %{environment: "development" }}
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Resource attributes in the `resource` Application environment variable are
flattened and combined with `.`, so

View File

@ -58,20 +58,20 @@ This tells the SDK to sample spans such that only 10% of Traces get created.
Example in the Application configuration with a root sampler for sampling 10% of
Traces and using the parent decision in the other cases:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% config/sys.config.src
{sampler, {parent_based, #{root => {trace_id_ratio_based, 0.10},
remote_parent_sampled => always_on,
remote_parent_not_sampled => always_off,
local_parent_sampled => always_on,
local_parent_not_sampled => always_off}}}
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# config/runtime.exs
sampler: {:parent_based, %{root: {:trace_id_ratio_based, 0.10},
remote_parent_sampled: :always_on,
@ -79,12 +79,9 @@ sampler: {:parent_based, %{root: {:trace_id_ratio_based, 0.10},
local_parent_sampled: :always_on,
local_parent_not_sampled: :always_off}}
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
<!-- markdownlint-disable heading-increment -->
{{% /tab %}} {{< /tabpane >}}
### AlwaysOn and AlwaysOff Sampler
@ -111,20 +108,20 @@ export OTEL_TRACES_SAMPLER="parentbased_always_off"
Here's an example in the Application configuration with a root sampler that
always samples and using the parent decision in the other cases:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% config/sys.config.src
{sampler, {parent_based, #{root => always_on,
remote_parent_sampled => always_on,
remote_parent_not_sampled => always_off,
local_parent_sampled => always_on,
local_parent_not_sampled => always_off}}}
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# config/runtime.exs
sampler: {:parent_based, %{root: :always_on,
remote_parent_sampled: :always_on,
@ -132,11 +129,9 @@ sampler: {:parent_based, %{root: :always_on,
local_parent_sampled: :always_on,
local_parent_not_sampled: :always_off}}
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Custom Sampler
@ -144,11 +139,9 @@ Custom samplers can be created by implementing the
[`otel_sampler` behaviour](https://hexdocs.pm/opentelemetry/1.3.0/otel_sampler.html#callbacks).
This example sampler:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
-module(attribute_sampler).
-behavior(otel_sampler).
@ -174,9 +167,11 @@ should_sample(_Ctx, _TraceId, _Links, _SpanName, _SpanKind, Attributes, ConfigAt
_ ->
{?RECORD_AND_SAMPLE, [], []}
end.
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
defmodule AttributesSampler do
def setup(attributes) when is_map(attributes) do
attributes
@ -199,11 +194,9 @@ defmodule AttributesSampler do
end
end
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Will sample Spans that do not have any attributes that match the attributes
passed as the sampler's configuration.
@ -211,18 +204,16 @@ passed as the sampler's configuration.
Example configuration to not sample any Span with an attribute specifying the
URL requested is `/healthcheck`:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
{sampler, {attributes_sampler, #{'http.target' => <<"/healthcheck">>}}}
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
sampler: {AttributesSampler, %{"http.target": "/healthcheck"}}
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}

View File

@ -15,45 +15,43 @@ validation.
Only the `opentelemetry` and `opentelemetry_api` libraries are required for
testing in Elixir/Erlang:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
{deps, [{opentelemetry_api, "~> {{% param versions.otelApi %}}"},
{opentelemetry, "~> {{% param versions.otelSdk %}}"}]}.
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
def deps do
[
{:opentelemetry_api, "~> {{% param versions.otelApi %}}"},
{:opentelemetry, "~> {{% param versions.otelSdk %}}"}
]
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Set your `exporter` to `:none` and the span processor to
`:otel_simple_processor`. This ensure that your tests don't actually export data
to a destination, and that spans can be analyzed after they are processed.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% config/sys.config.src
{opentelemetry,
[{traces_exporter, none},
{processors,
[{otel_simple_processor, #{}}]}]}
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# config/test.exs
import Config
@ -63,21 +61,17 @@ config :opentelemetry,
config :opentelemetry, :processors, [
{:otel_simple_processor, %{}}
]
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
A modified version of the `hello` function from the
[Getting Started](/docs/instrumentation/erlang/getting-started/) guide will
serve as our test case:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
%% apps/otel_getting_started/src/otel_getting_started.erl
-module(otel_getting_started).
@ -92,9 +86,11 @@ hello() ->
nice_operation(_SpanCtx) ->
?set_attributes([{a_key, <<"a value">>}]),
world
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
# lib/otel_getting_started.ex
defmodule OtelGettingStarted do
require OpenTelemetry.Tracer, as: Tracer
@ -106,19 +102,15 @@ defmodule OtelGettingStarted do
end
end
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Testing
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Erlang %}}
{{< tab Erlang >}}
```erlang
-module(otel_getting_started_SUITE).
-compile(export_all).
@ -170,9 +162,11 @@ greets_the_world(_Config) ->
?assertMatch(ReceivedAttributes, ExpectedAttributes),
ok.
{{< /tab >}}
```
{{< tab Elixir >}}
{{% /tab %}} {{% tab Elixir %}}
```elixir
defmodule OtelGettingStartedTest do
use ExUnit.Case
@ -202,8 +196,6 @@ defmodule OtelGettingStartedTest do
)}
end
end
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}

View File

@ -27,30 +27,20 @@ update `instrumentation.ts|js` from the
[Getting Started](/docs/instrumentation/js/getting-started/nodejs/) like the
following:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Typescript %}}
{{< tabpane langEqualsHeader=true >}}
{{< tab Typescript >}}
```ts
/*instrumentation.ts*/
import * as opentelemetry from "@opentelemetry/sdk-node";
import {
getNodeAutoInstrumentations,
} from "@opentelemetry/auto-instrumentations-node";
import {
OTLPTraceExporter,
} from "@opentelemetry/exporter-trace-otlp-proto";
import {
OTLPMetricExporter
} from "@opentelemetry/exporter-metrics-otlp-proto";
import {
PeriodicExportingMetricReader
} from "@opentelemetry/sdk-metrics";
import * as opentelemetry from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
const sdk = new opentelemetry.NodeSDK({
traceExporter: new OTLPTraceExporter({
// optional - default url is http://localhost:4318/v1/traces
url: "<your-otlp-endpoint>/v1/traces",
url: '<your-otlp-endpoint>/v1/traces',
// optional - collection of custom headers to be sent with each request, empty by default
headers: {},
}),
@ -63,28 +53,28 @@ const sdk = new opentelemetry.NodeSDK({
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```js
/*instrumentation.js*/
const opentelemetry = require("@opentelemetry/sdk-node");
const opentelemetry = require('@opentelemetry/sdk-node');
const {
getNodeAutoInstrumentations,
} = require("@opentelemetry/auto-instrumentations-node");
} = require('@opentelemetry/auto-instrumentations-node');
const {
OTLPTraceExporter,
} = require("@opentelemetry/exporter-trace-otlp-proto");
} = require('@opentelemetry/exporter-trace-otlp-proto');
const {
OTLPMetricExporter
} = require("@opentelemetry/exporter-metrics-otlp-proto");
const {
PeriodicExportingMetricReader
} = require('@opentelemetry/sdk-metrics');
OTLPMetricExporter,
} = require('@opentelemetry/exporter-metrics-otlp-proto');
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const sdk = new opentelemetry.NodeSDK({
traceExporter: new OTLPTraceExporter({
// optional - default url is http://localhost:4318/v1/traces
url: "<your-otlp-endpoint>/v1/traces",
url: '<your-otlp-endpoint>/v1/traces',
// optional - collection of custom headers to be sent with each request, empty by default
headers: {},
}),
@ -98,12 +88,9 @@ const sdk = new opentelemetry.NodeSDK({
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
{{< /tab >}}
```
{{< /tabpane>}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
To try out the `OTLPTraceExporter` quickly, you can run Jaeger in a docker
container:
@ -249,25 +236,25 @@ npm install --save @opentelemetry/exporter-zipkin
Update your OpenTelemetry configuration to use the exporter and to send data to
your Zipkin backend:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tab Typescript >}}
import { ZipkinExporter } from "@opentelemetry/exporter-zipkin";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
{{< tabpane text=true langEqualsHeader=true >}} {{% tab Typescript %}}
```ts
import { ZipkinExporter } from '@opentelemetry/exporter-zipkin';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
provider.addSpanProcessor(new BatchSpanProcessor(new ZipkinExporter()));
{{< /tab>}}
```
{{< tab JavaScript >}}
const { ZipkinExporter } = require("@opentelemetry/exporter-zipkin");
const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
{{% /tab %}} {{% tab JavaScript %}}
```js
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
provider.addSpanProcessor(new BatchSpanProcessor(new ZipkinExporter()));
{{< /tab >}}
{{< /tabpane>}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
```
{{% /tab %}} {{< /tabpane >}}
[content security policies]:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/

View File

@ -86,16 +86,19 @@ Create an empty code file named `document-load` with a `.ts` or `.js` extension,
as appropriate, based on the language you've chosen to write your app in. Add
the following code to your HTML right before the `</body>` closing tag:
<!-- prettier-ignore-start -->
{{< tabpane lang=html >}}
{{< tab TypeScript >}}
{{< tabpane text=true >}} {{% tab TypeScript %}}
```html
<script type="module" src="document-load.ts"></script>
{{< /tab >}}
{{< tab JavaScript >}}
```
{{% /tab %}} {{% tab JavaScript %}}
```html
<script type="module" src="document-load.js"></script>
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
```
{{% /tab %}} {{< /tabpane >}}
We will add some code that will trace the document load timings and output those
as OpenTelemetry Spans.

View File

@ -39,45 +39,43 @@ npm init -y
Next, install Express dependencies.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```sh
npm install typescript \
ts-node \
@types/node \
express \
@types/express
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```sh
npm install express
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
### Create and launch an HTTP Server
Create a file named `app.ts` (or `app.js` if not using TypeScript) and add the
following code to it:
{{% tabpane text=true %}} {{% tab TypeScript %}}
{{% tabpane text=true langEqualsHeader=true %}} {{% tab TypeScript %}}
```TypeScript
```ts
/*app.ts*/
import express, { Express } from "express";
import express, { Express } from 'express';
const PORT: number = parseInt(process.env.PORT || "8080");
const PORT: number = parseInt(process.env.PORT || '8080');
const app: Express = express();
function getRandomNumber(min: number, max: number) {
return Math.floor(Math.random() * (max - min) + min);
}
app.get("/rolldice", (req, res) => {
app.get('/rolldice', (req, res) => {
res.send(getRandomNumber(1, 6).toString());
});
@ -88,18 +86,18 @@ app.listen(PORT, () => {
{{% /tab %}} {{% tab JavaScript %}}
```JavaScript
```js
/*app.js*/
const express = require("express");
const express = require('express');
const PORT = parseInt(process.env.PORT || "8080");
const PORT = parseInt(process.env.PORT || '8080');
const app = express();
function getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
app.get("/rolldice", (req, res) => {
app.get('/rolldice', (req, res) => {
res.send(getRandomNumber(1, 6).toString());
});
@ -108,28 +106,26 @@ app.listen(PORT, () => {
});
```
{{% /tab %}} {{% /tabpane%}}
{{% /tab %}} {{% /tabpane %}}
Run the application with the following command and open
<http://localhost:8080/rolldice> in your web browser to ensure it is working.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=console >}}
{{< tabpane text=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```console
$ npx ts-node app.ts
Listening for requests on http://localhost:8080
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```console
$ node app.js
Listening for requests on http://localhost:8080
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Instrumentation
@ -167,76 +163,77 @@ application code. One tool commonly used for this task is the
Create a file named `instrumentation.ts` (or `instrumentation.js` if not using
TypeScript) , which will contain your instrumentation setup code.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```ts
/*instrumentation.ts*/
import { NodeSDK } from '@opentelemetry/sdk-node';
import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { PeriodicExportingMetricReader, ConsoleMetricExporter } from '@opentelemetry/sdk-metrics';
import {
PeriodicExportingMetricReader,
ConsoleMetricExporter,
} from '@opentelemetry/sdk-metrics';
const sdk = new NodeSDK({
traceExporter: new ConsoleSpanExporter(),
metricReader: new PeriodicExportingMetricReader({
exporter: new ConsoleMetricExporter()
exporter: new ConsoleMetricExporter(),
}),
instrumentations: [getNodeAutoInstrumentations()]
instrumentations: [getNodeAutoInstrumentations()],
});
sdk
.start()
sdk.start();
```
{{< /tab >}}
{{% /tab %}} {{% tab JavaScript %}}
{{< tab JavaScript >}}
```js
/*instrumentation.js*/
// Require dependencies
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { PeriodicExportingMetricReader, ConsoleMetricExporter } = require('@opentelemetry/sdk-metrics');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const {
PeriodicExportingMetricReader,
ConsoleMetricExporter,
} = require('@opentelemetry/sdk-metrics');
const sdk = new NodeSDK({
traceExporter: new ConsoleSpanExporter(),
metricReader: new PeriodicExportingMetricReader({
exporter: new ConsoleMetricExporter()
exporter: new ConsoleMetricExporter(),
}),
instrumentations: [getNodeAutoInstrumentations()]
instrumentations: [getNodeAutoInstrumentations()],
});
sdk
.start()
{{< /tab >}}
sdk.start();
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Run the instrumented app
Now you can run your application as you normally would, but you can use the
`--require` flag to load the instrumentation before the application code.
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane lang=console >}}
{{< tabpane text=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```console
$ npx ts-node --require ./instrumentation.ts app.ts
Listening for requests on http://localhost:8080
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```console
$ node --require ./instrumentation.js app.js
Listening for requests on http://localhost:8080
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
Open <http://localhost:8080/rolldice> in your web browser and reload the page a
few times. After a while you should see the spans printed in the console by the
@ -479,11 +476,9 @@ If you'd like to explore a more complex example, take a look at the
Did something go wrong? You can enable diagnostic logging to validate that
OpenTelemetry is initialized correctly:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```ts
/*instrumentation.ts*/
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
@ -491,9 +486,11 @@ import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
// const sdk = new NodeSDK({...
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```js
/*instrumentation.js*/
// Require dependencies
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
@ -502,11 +499,9 @@ const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
// const sdk = new NodeSDK({...
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
[traces]: /docs/concepts/signals/traces/
[metrics]: /docs/concepts/signals/metrics/

View File

@ -44,89 +44,89 @@ npm install @opentelemetry/auto-instrumentations-node
Then in your tracing initialization code, use `registerInstrumentations`:
<!-- textlint-disable -->
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```ts
/* tracing.ts */
// Import dependencies
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import opentelemetry from "@opentelemetry/api";
import { Resource } from "@opentelemetry/resources";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { ConsoleSpanExporter, BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import opentelemetry from '@opentelemetry/api';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import {
ConsoleSpanExporter,
BatchSpanProcessor,
} from '@opentelemetry/sdk-trace-base';
// This registers all instrumentation packages
registerInstrumentations({
instrumentations: [
getNodeAutoInstrumentations()
],
instrumentations: [getNodeAutoInstrumentations()],
});
const resource =
Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: "service-name-here",
[SemanticResourceAttributes.SERVICE_VERSION]: "0.1.0",
})
);
const resource = Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'service-name-here',
[SemanticResourceAttributes.SERVICE_VERSION]: '0.1.0',
}),
);
const provider = new NodeTracerProvider({
resource: resource,
resource: resource,
});
const exporter = new ConsoleSpanExporter();
const processor = new BatchSpanProcessor(exporter);
provider.addSpanProcessor(processor);
provider.register();
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```js
/* tracing.js */
// Require dependencies
const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node");
const opentelemetry = require("@opentelemetry/api");
const { Resource } = require("@opentelemetry/resources");
const { SemanticResourceAttributes } = require("@opentelemetry/semantic-conventions");
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
const { ConsoleSpanExporter, BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const opentelemetry = require('@opentelemetry/api');
const { Resource } = require('@opentelemetry/resources');
const {
SemanticResourceAttributes,
} = require('@opentelemetry/semantic-conventions');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const {
ConsoleSpanExporter,
BatchSpanProcessor,
} = require('@opentelemetry/sdk-trace-base');
// This registers all instrumentation packages
registerInstrumentations({
instrumentations: [
getNodeAutoInstrumentations()
],
instrumentations: [getNodeAutoInstrumentations()],
});
const resource =
Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: "service-name-here",
[SemanticResourceAttributes.SERVICE_VERSION]: "0.1.0",
})
);
const resource = Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'service-name-here',
[SemanticResourceAttributes.SERVICE_VERSION]: '0.1.0',
}),
);
const provider = new NodeTracerProvider({
resource: resource,
resource: resource,
});
const exporter = new ConsoleSpanExporter();
const processor = new BatchSpanProcessor(exporter);
provider.addSpanProcessor(processor);
provider.register();
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
<!-- textlint-enable -->
{{% /tab %}} {{< /tabpane >}}
### Using individual instrumentation packages
@ -145,22 +145,23 @@ npm install --save @opentelemetry/instrumentation-http @opentelemetry/instrument
And then register each instrumentation library:
<!-- markdownlint-disable -->
<!-- prettier-ignore-start -->
{{< tabpane langEqualsHeader=true >}}
{{< tabpane text=true langEqualsHeader=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```ts
/* tracing.ts */
// Import dependencies
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
import opentelemetry from "@opentelemetry/api";
import { Resource } from "@opentelemetry/resources";
import { SemanticResourceAttributes } from "@opentelemetry/semantic-conventions";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { ConsoleSpanExporter, BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
import opentelemetry from '@opentelemetry/api';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import {
ConsoleSpanExporter,
BatchSpanProcessor,
} from '@opentelemetry/sdk-trace-base';
// This registers all instrumentation packages
registerInstrumentations({
@ -171,36 +172,44 @@ registerInstrumentations({
],
});
const resource =
Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: "service-name-here",
[SemanticResourceAttributes.SERVICE_VERSION]: "0.1.0",
})
);
const resource = Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'service-name-here',
[SemanticResourceAttributes.SERVICE_VERSION]: '0.1.0',
}),
);
const provider = new NodeTracerProvider({
resource: resource,
resource: resource,
});
const exporter = new ConsoleSpanExporter();
const processor = new BatchSpanProcessor(exporter);
provider.addSpanProcessor(processor);
provider.register();
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```js
/* tracing.js */
// Require dependencies
const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
const { ExpressInstrumentation } = require("@opentelemetry/instrumentation-express");
const opentelemetry = require("@opentelemetry/api");
const { Resource } = require("@opentelemetry/resources");
const { SemanticResourceAttributes } = require("@opentelemetry/semantic-conventions");
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
const { registerInstrumentations } = require("@opentelemetry/instrumentation");
const { ConsoleSpanExporter, BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const {
ExpressInstrumentation,
} = require('@opentelemetry/instrumentation-express');
const opentelemetry = require('@opentelemetry/api');
const { Resource } = require('@opentelemetry/resources');
const {
SemanticResourceAttributes,
} = require('@opentelemetry/semantic-conventions');
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const {
ConsoleSpanExporter,
BatchSpanProcessor,
} = require('@opentelemetry/sdk-trace-base');
// This registers all instrumentation packages
registerInstrumentations({
@ -211,27 +220,24 @@ registerInstrumentations({
],
});
const resource =
Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: "service-name-here",
[SemanticResourceAttributes.SERVICE_VERSION]: "0.1.0",
})
);
const resource = Resource.default().merge(
new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'service-name-here',
[SemanticResourceAttributes.SERVICE_VERSION]: '0.1.0',
}),
);
const provider = new NodeTracerProvider({
resource: resource,
resource: resource,
});
const exporter = new ConsoleSpanExporter();
const processor = new BatchSpanProcessor(exporter);
provider.addSpanProcessor(processor);
provider.register();
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
<!-- markdownlint-restore -->
{{% /tab %}} {{< /tabpane >}}
## Configuring instrumentation libraries

File diff suppressed because it is too large Load Diff

View File

@ -34,10 +34,9 @@ This tells the SDK to sample spans such that only 10% of traces get created.
You can also configure the TraceIdRatioBasedSampler in code. Here's an example
for Node.js:
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
```ts
import { TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-node';
const samplePercentage = 0.1;
@ -46,9 +45,11 @@ const sdk = new NodeSDK({
// Other SDK configuration parameters go here
sampler: new TraceIdRatioBasedSampler(samplePercentage),
});
{{< /tab >}}
```
{{< tab JavaScript >}}
{{% /tab %}} {{% tab JavaScript %}}
```js
const { TraceIdRatioBasedSampler } = require('@opentelemetry/sdk-trace-node');
const samplePercentage = 0.1;
@ -57,38 +58,43 @@ const sdk = new NodeSDK({
// Other SDK configuration parameters go here
sampler: new TraceIdRatioBasedSampler(samplePercentage),
});
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
{{% /tab %}} {{< /tabpane >}}
### Browser
You can also configure the TraceIdRatioBasedSampler in code. Here's an example
for browser apps:
<!-- prettier-ignore-start -->
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab TypeScript %}}
{{< tab TypeScript >}}
import { WebTracerProvider, TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-web';
```ts
import {
WebTracerProvider,
TraceIdRatioBasedSampler,
} from '@opentelemetry/sdk-trace-web';
const samplePercentage = 0.1;
const provider = new WebTracerProvider({
sampler: new TraceIdRatioBasedSampler(samplePercentage),
sampler: new TraceIdRatioBasedSampler(samplePercentage),
});
{{< /tab >}}
```
{{< tab JavaScript >}}
const { WebTracerProvider, TraceIdRatioBasedSampler } = require('@opentelemetry/sdk-trace-web');
{{% /tab %}} {{% tab JavaScript %}}
```js
const {
WebTracerProvider,
TraceIdRatioBasedSampler,
} = require('@opentelemetry/sdk-trace-web');
const samplePercentage = 0.1;
const provider = new WebTracerProvider({
sampler: new TraceIdRatioBasedSampler(samplePercentage),
sampler: new TraceIdRatioBasedSampler(samplePercentage),
});
{{< /tab >}}
```
{{< /tabpane >}}
<!-- prettier-ignore-end -->
{{% /tab %}} {{< /tabpane >}}

View File

@ -84,28 +84,42 @@ The extension can be installed via pecl,
1. Setup development environment. Installing from source requires proper
development environment and some dependencies:
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab "Linux (apt)" %}}
{{< tab "Linux (apt)" >}}sudo apt-get install gcc make autoconf{{< /tab >}}
```sh
sudo apt-get install gcc make autoconf
```
{{< tab "macOS (homebrew)" >}}brew install gcc make autoconf{{< /tab >}}
{{% /tab %}} {{% tab "macOS (homebrew)" %}}
{{< /tabpane >}}
```sh
brew install gcc make autoconf
```
{{% /tab %}} {{< /tabpane >}}
2. Build/install the extension. With your environment set up you can install the
extension:
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab pecl %}}
{{< tab pecl >}}pecl install opentelemetry-beta{{< /tab >}}
<!-- prettier-ignore-start -->
```sh
pecl install opentelemetry-beta
```
{{< tab pickle >}}php pickle.phar install opentelemetry{{< /tab >}}
<!-- prettier-ignore-end -->
<!-- prettier-ignore -->
{{< tab "php-extension-installer (docker)" >}}install-php-extensions opentelemetry{{< /tab >}}
{{% /tab %}} {{% tab pickle %}}
{{< /tabpane >}}
```sh
php pickle.phar install opentelemetry
```
{{% /tab %}} {{% tab "php-extension-installer (docker)" %}}
```sh
install-php-extensions opentelemetry
```
{{% /tab %}} {{< /tabpane >}}
3. Add the extension to your `php.ini` file:

View File

@ -30,10 +30,9 @@ composer require open-telemetry/transport-grpc
Next, configure an exporter with an OTLP endpoint. For example:
<!-- prettier-ignore-start -->
{{< tabpane >}} {{< tab gRPC >}}
{{< tabpane text=true >}} {{% tab gRPC %}}
```php
<?php
require __DIR__ . '/vendor/autoload.php';
@ -51,8 +50,11 @@ $exporter = new SpanExporter($transport);
$tracerProvider = new TracerProvider(
new SimpleSpanProcessor($exporter)
);
{{< /tab >}}
{{< tab protobuf >}}
```
{{% /tab %}} {{% tab protobuf %}}
```php
<?php
require __DIR__ . '/vendor/autoload.php';
@ -68,8 +70,11 @@ $exporter = new SpanExporter($transport);
$tracerProvider = new TracerProvider(
new SimpleSpanProcessor($exporter)
);
{{< /tab>}}
{{< tab json >}}
```
{{% /tab %}} {{% tab JSON %}}
```php
<?php
require __DIR__ . '/vendor/autoload.php';
@ -87,8 +92,11 @@ $tracerProvider = new TracerProvider(
);
$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');
$tracer->spanBuilder('example')->startSpan()->end();
{{< /tab >}}
{{< tab nd-json >}}
```
{{% /tab %}} {{% tab NDJSON %}}
```php
<?php
require __DIR__ . '/vendor/autoload.php';
@ -106,9 +114,9 @@ $tracerProvider = new TracerProvider(
);
$tracer = $tracerProvider->getTracer('io.opentelemetry.contrib.php');
$tracer->spanBuilder('example')->startSpan()->end();
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
```
{{% /tab %}} {{< /tabpane >}}
Then, append the following code to generate a span:
@ -180,5 +188,6 @@ will not hold up request processing.
To minimize the impact of slow transport of telemetry data, particularly for
external or cloud-based backends, you should consider using the
[OpenTelemetry Collector](/docs/collector/) as an [agent](/docs/collector/deployment/agent/). The agent can quickly
accept, then batch send telemetry data to the backend.
[OpenTelemetry Collector](/docs/collector/) as an
[agent](/docs/collector/deployment/agent/). The agent can quickly accept, then
batch send telemetry data to the backend.

View File

@ -102,13 +102,19 @@ Next, youll use the OpenTelemetry PHP extension to
1. Since the extension is built from source, you need to install some build
tools
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab "Linux (apt)" %}}
{{< tab "Linux (apt)" >}}sudo apt-get install gcc make autoconf{{< /tab >}}
```sh
sudo apt-get install gcc make autoconf
```
{{< tab "macOS (homebrew)" >}}brew install gcc make autoconf{{< /tab >}}
{{% /tab %}} {{% tab "macOS (homebrew)" %}}
{{< /tabpane >}}
```sh
brew install gcc make autoconf
```
{{% /tab %}} {{< /tabpane >}}
2. Build the extension with `PECL`:

View File

@ -338,22 +338,28 @@ The OpenTelemetry SDK provides four samplers:
which is used to determine if a root span (a span without a parent) should be
sampled. The root sampler can be any of the other samplers.
<!-- prettier-ignore-start -->
{{< tabpane lang=php >}}
{{< tab "TraceId ratio-based" >}}
//trace 50% of requests
{{< tabpane text=true >}} {{% tab "TraceId ratio-based" %}}
```php
// Trace 50% of requests
$sampler = new TraceIdRatioBasedSampler(0.5);
{{< /tab >}}
{{< tab "Always On" >}}
//always trace
```
{{% /tab %}} {{% tab "Always On" %}}
```php
// Always trace
$sampler = new AlwaysOnSampler();
{{< /tab >}}
{{< tab "Parent-based + ratio-based" >}}
//always sample if the parent is sampled, otherwise only sample 10% of spans
```
{{% /tab %}} {{% tab "Parent-based + ratio-based" %}}
```php
// Always sample if the parent is sampled, otherwise only sample 10% of spans
$sampler = new ParentBased(new TraceIdRatioBasedSampler(0.1));
{{< /tab >}}
{{< /tabpane >}}
<!-- prettier-ignore-end -->
```
{{% /tab %}} {{< /tabpane >}}
```php
$tracerProvider = TracerProvider::builder()

View File

@ -17,13 +17,19 @@ To send trace data to a OTLP endpoint (like the [collector](/docs/collector) or
Jaeger) you'll want to use an exporter package, such as
`opentelemetry-exporter-otlp`:
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab bundler %}}
{{< tab bundler >}} bundle add opentelemetry-exporter-otlp {{< /tab >}}
```sh
bundle add opentelemetry-exporter-otlp
```
{{< tab gem >}} gem install opentelemetry-exporter-otlp {{< /tab >}}
{{% /tab %}} {{% tab gem %}}
{{< /tabpane>}}
```sh
gem install opentelemetry-exporter-otlp
```
{{% /tab %}} {{< /tabpane >}}
Next, configure the exporter to point at an OTLP endpoint. For example you can
update `config/initializers/opentelemetry.rb` from the
@ -85,13 +91,19 @@ docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin
Install the exporter package as a dependency for your application:
{{< tabpane lang=shell >}}
{{< tabpane text=true >}} {{% tab bundle %}}
{{< tab bundle >}} bundle add opentelemetry-exporter-zipkin {{< /tab >}}
```sh
bundle add opentelemetry-exporter-zipkin
```
{{< tab gem >}} gem install opentelemetry-exporter-zipkin {{< /tab >}}
{{% /tab %}} {{% tab gem %}}
{{< /tabpane>}}
```sh
gem install opentelemetry-exporter-zipkin
```
{{% /tab %}} {{< /tabpane >}}
Update your OpenTelemetry configuration to use the exporter and to send data to
your Zipkin backend:

64
scripts/norm-tabpanes.pl Executable file
View File

@ -0,0 +1,64 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use FileHandle;
my $in_tabpane = 0;
my $in_tab = 0;
my $tab_title = '';
my $lang = '';
my $langIsHeader = 0;
for my $filename (@ARGV) {
my $fh = FileHandle->new("< $filename") or die "Can't open $filename: $!";
my @lines = <$fh>;
$fh->close;
for (my $i = 0; $i < @lines; $i++) {
if ($lines[$i] =~ /\{\{<\s*tabpane(.*?)>\}\}\s*$/) {
$in_tabpane = 1;
my $args = $1;
$langIsHeader = $args =~ /langEqualsHeader="?true"?/;
($lang) = $args =~ /\blang="?(.*?)"?\b/;
$lang =~ s/^shell$/sh/ if $lang;
$lines[$i] =~ s/tabpane /tabpane text=true /;
# Remove comment lines before tabpane and optional blank line
while (($i > 0 && $lines[$i-1] =~ /<!-- (prettier|\w+lint).*? -->/)
|| ($i > 1 && $lines[$i-2] =~ /<!-- (prettier|\w+lint).*? -->/)) {
splice @lines, --$i, 1;
}
} elsif ($in_tabpane && $lines[$i] =~ /\{\{<\s*tab\s+([^>]*\S)\s*>\}\}/) {
$in_tab = 1;
$tab_title = $1;
# Remove blank line before end tag if present
splice @lines, --$i, 1 if $i > 1 && ($lines[$i-1] =~ /^\s*$/);
$lang = $tab_title if $langIsHeader;
$lang = 'js' if $lang eq 'JavaScript';
$lang = 'ts' if $lang eq 'TypeScript';
if ($lang) {
$lang = lc($lang);
} else {
printf STDERR "$filename:$i - no language specified\n";
}
$lines[$i] = "{{% tab $tab_title %}}\n\n```$lang\n";
} elsif ($in_tab && $lines[$i] =~ /\{\{<\s*\/tab\s*>\}\}/) {
$in_tab = 0;
$lines[$i] = "```\n\n{{% /tab %}}\n";
} elsif ($in_tabpane && $lines[$i] =~ /\{\{<\s*\/tabpane\s*>\}\}/) {
$in_tabpane = 0;
$langIsHeader = 0;
# Remove blank line before end tag if present
splice @lines, --$i, 1 if $i > 2 && ($lines[$i-1] =~ /^\s*$/) && ($lines[$i-2] =~ /\/tab/);
# Remove comment lines after tabpane and optional blank line
while (($i + 0 < $#lines && $lines[$i+1] =~ /<!-- (prettier|\w+lint).*? -->/)
|| ($i + 1 < $#lines && $lines[$i+2] =~ /<!-- (prettier|\w+lint).*? -->/)) {
splice @lines, $i+1, 1;
}
}
}
$fh = FileHandle->new("> $filename") or die "Can't open $filename: $!";
print $fh @lines;
$fh->close;
}