Normalize tabpane shortcode use (#3137)
This commit is contained in:
parent
6094eda3f7
commit
526347d242
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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") {...}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 >}}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 don’t 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 >}}
|
||||
|
|
|
|||
|
|
@ -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 >}}
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 >}}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -102,13 +102,19 @@ Next, you’ll 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`:
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue