Skip to main content
This page shows how to send traces and metrics from your Rust application to AppSignal with OpenTelemetry. When you’re done, the spans your application creates with the tracing crate appear on the “Performance > Traces” page in AppSignal. Make sure to install the AppSignal collector before proceeding with these instructions.

Install the OpenTelemetry crates

Use Cargo to add the OpenTelemetry SDK, the OTLP exporter, the tracing integration, and the crates the configuration below uses to your application’s dependencies:
Which versions work together, and what some of these crates and features do:
  • tracing-opentelemetry: its version must match the OpenTelemetry crates. Version 0.29 of tracing-opentelemetry works with version 0.28 of opentelemetry, opentelemetry_sdk, and opentelemetry-otlp. If you upgrade one, upgrade the other to a matching version.
  • reqwest-rustls: this feature lets the exporter send data to https:// collector URLs, such as a hosted collector.
  • nix: looks up the hostname of the machine your application runs on, which the configuration reports as host.name.
  • env-filter: this tracing-subscriber feature lets you choose which spans to report with the RUST_LOG environment variable.

Configure OpenTelemetry in your application

Add this appsignal.rs module to your application’s src directory, next to main.rs. It sets up the exporters that send traces and metrics to the AppSignal collector, and the attributes AppSignal uses to recognize your application. Before you run it, update these values at the top of initialize_opentelemetry:
  • name: your AppSignal application name.
  • environment: the environment your application runs in, such as development, staging, or production.
  • push_api_key: your organization-level Push API key, which you can find on the Push & deploy settings page.
  • endpoint: keep http://localhost:8099 if the collector runs on the same machine as your application. Otherwise, use the address of your collector. For a hosted collector, open the “Hosted Collector” page in your organization’s settings, open your collector, and copy its “Collector URL”. If the list is empty, create a collector there first.
The code reports your application’s version from Cargo.toml as the revision. AppSignal uses the revision to create a deploy marker each time you deploy a new version. A revision can be a version number or a Git commit SHA. Cargo adds the version to the binary when it compiles your application. The revision is then set even when you build on a CI service, such as GitHub Actions, and run the binary without a Git repository. Bump the version in Cargo.toml with each release, for example when you create a GitHub release. Each deploy then gets its own deploy marker.

Start your application with OpenTelemetry

Call the initialize_opentelemetry function at the start of your application’s main function, so spans created during startup are reported too. Pass it the name of the service that’s being monitored. AppSignal groups traces by service name, so choose a name that describes this part of your application, such as “Web server” or “Background worker”. Before your application exits, call shutdown to send the remaining traces and metrics to the AppSignal collector. The example below uses the Tokio runtime. If your application doesn’t use Tokio yet, add it with cargo add tokio@1 --features full. The appsignal.rs module also prints your application’s logs to the console. If your application already sets up logging with tracing_subscriber, such as with tracing_subscriber::fmt::init(), remove that call. tracing_subscriber can only be set up once, so your application panics at startup if both run.
If your application is a web server, it usually runs until it receives a stop signal, such as SIGTERM during a deploy. Make it shut down gracefully when it receives one, so the server stops, main continues, and the shutdown call runs. For example, use with_graceful_shutdown in axum. Without a graceful shutdown, your application exits before calling shutdown, and the traces and metrics it hasn’t sent yet are lost.

Create spans with the tracing crate

The appsignal.rs module reports the spans that your application creates with the tracing crate to AppSignal. For example, add the #[tracing::instrument] attribute to a function to create a span each time it’s called. Each call to this checkout function creates a span named checkout:
The #[tracing::instrument] attribute creates spans at the info level by default. The appsignal.rs module reports spans at the info level and above, so these spans reach AppSignal without extra configuration. To also report debug spans, start your application with the RUST_LOG environment variable set to debug:

Test the app!

Now that all the components are connected, start your app and use it so it creates spans, for example by sending a few requests to it. Then open the “Performance > Traces” page in AppSignal to see the traces arrive.
Errors that you record with the tracing crate don’t appear on the “Errors > Issue list” page. The tracing-opentelemetry crate records them without the exception.type attribute, which AppSignal needs to report an error.
If after following our installation instructions you still don’t see data in AppSignal, let us know and we’ll help you finalize your OpenTelemetry installation!