OpenTelemetry Beta

The OpenTelemetry beta involves more installation steps than usual. Please ensure you follow all the steps carefully to set it up correctly.

Previous versions of this documentation described how to install the standalone agent. This is no longer recommended. The AppSignal Collector replaces the standalone agent for this beta. Installation and configuration works differently in the collector, so we recommend following this guide again and updating the your application if necessary.

Install the AppSignal collector

To report data to AppSignal, you need to install the AppSignal collector via one of the following installation methods:

Configuring the AppSignal collector

When configuring the collector, use the organization-level Push API key from the API keys settings page. This will authenticate requests with AppSignal. Without a Push API key the collector will not start.

Linux package
Docker run
Docker Compose
Linux package
# /etc/appsignal-collector.conf push_api_key = "0000-0000-0000-0000"
Docker run
docker run \ --env APPSIGNAL_PUSH_API_KEY="0000-0000-0000-0000" \ --publish "8099:8099" \ appsignal/collector
Docker Compose
version: "3.8" services: appsignal-collector: image: appsignal/collector:latest environment: - APPSIGNAL_PUSH_API_KEY="0000-0000-0000-0000"

Install the OpenTelemetry packages

To install the OpenTelemetry packages in your app follow the OpenTelemetry installation instructions for the language your app uses.

Below are links to OpenTelemetry getting started guides for some popular languages:

  • Ruby, the "Instrumentation" section.
  • Elixir, the "Dependencies" section.
  • Node.js, the "Instrumentation" section.
  • Python, the "Setup" section.
  • Go, the "Add OpenTelemetry Instrumentation" section.
  • Rust, the "Instrumentation" section.
  • PHP, the "Add zero-code instrumentation" or "Add manual instrumentation" section.
  • Java, the "Instrumentation" section.

Also follow any additional steps needed to have OpenTelemetry instrument your application, instrument specific libraries, and setting up a tracer and creating spans where needed.

Below are examples for a couple languages:

Ruby
Elixir
Node.js
Python
Ruby
# Run Bundler add to add OpenTelemetry packages to your app's bundle bundle add opentelemetry-sdk opentelemetry-exporter-otlp opentelemetry-instrumentation-all
Elixir
# mix.exs def deps do [ # other default deps... {:opentelemetry, "~> 1.3"}, {:opentelemetry_api, "~> 1.2"}, {:opentelemetry_exporter, "~> 1.6"}, # Add any other instrumentation packages for libraries you use {:opentelemetry_phoenix, "~> 1.1"}, {:opentelemetry_cowboy, "~> 0.2"}, {:opentelemetry_ecto, "~> 1.2"} # if using ecto ] end
Node.js
# Node.js example only npm install @opentelemetry/sdk-node \ @opentelemetry/api \ @opentelemetry/sdk-trace-node \ @opentelemetry/sdk-metrics \ @opentelemetry/exporter-trace-otlp-http \ @opentelemetry/exporter-metrics-otlp-proto \ @opentelemetry/auto-instrumentations-node
Python
# requirements.txt opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-http # Add any other instrumentation packages for libraries you use # For example: # opentelemetry-instrumentation-aiopg # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-asyncpg # opentelemetry-instrumentation-celery # opentelemetry-instrumentation-django # opentelemetry-instrumentation-fastapi # opentelemetry-instrumentation-flask # opentelemetry-instrumentation-jinja2 # opentelemetry-instrumentation-mysql # opentelemetry-instrumentation-mysqlclient # opentelemetry-instrumentation-pika # opentelemetry-instrumentation-psycopg # opentelemetry-instrumentation-psycopg2 # opentelemetry-instrumentation-pymysql # opentelemetry-instrumentation-redis # opentelemetry-instrumentation-requests # opentelemetry-instrumentation-sqlalchemy # opentelemetry-instrumentation-sqlite3 # opentelemetry-instrumentation-starlette # opentelemetry-instrumentation-wsgi

Configure OpenTelemetry in your app

Configure OpenTelemetry in your application with the application details listed below. We will also configure the service name in OpenTelemetry and set up an HTTP exporter that exports OpenTelemetry tracing data to the AppSignal collector.

Configure the OpenTelemetry Resource with the SDK with the following required attributes:

  • appsignal.config.name: The application's name.
  • appsignal.config.environment: The application's environment.
  • appsignal.config.push_api_key: The application's Push API key. This can be the same Push API key as configured earlier in Install the AppSignal collector.
  • appsignal.config.revision: Automatically create deploys in AppSignal by specifying the app revision.
  • appsignal.config.language_integration: Set the programming language name to help us recognize what programming language the app data is from so we can optimize the tracing data. Example values: "python", "rust", "ruby", "elixir", "go", "node.js", etc.
  • service.name: The service's name as it should show up on AppSignal.com. See the Customize the service name in OpenTelemetry section for more details.
  • host.name: The name of the host as it should show up on AppSignal.com.

See also our configuration options page for a list of all supported config options.

If you already have an application that uses the same name and environment, reported by one of our existing language integration packages, please use another name and/or environment. This beta introduces new UI elements and pages that are not compatible with the data reported by our integration packages. We recommend reporting the application OpenTelemetry data to a new AppSignal application so the UI will not be so confusing.

Example configuration:

Add this appsignal.rb file to your application with the OpenTelemetry exporter and AppSignal configuration. Then require it in your application. For Rails applications, add it to an Rails initializer like config/initializers/appsignal.rb.

Update the Resource attributes to match your AppSignal configuration. Update the endpoint option for the collector if needed, see customizing the exporter.

Ruby
# opentelemetry.rb # Place this in an opentelemetry.rb file and require it in your app require "socket" require "opentelemetry/sdk" require "opentelemetry/instrumentation/all" require "opentelemetry-exporter-otlp" revision = `git rev-parse --short HEAD`.strip OpenTelemetry::SDK.configure do |c| # Add AppSignal and app configuration c.resource = OpenTelemetry::SDK::Resources::Resource.create( "appsignal.config.name" => "My app", # For Rails applications, use `Rails.env.to_s` "appsignal.config.environment" => "production", "appsignal.config.push_api_key" => "0000-0000-0000-0000", "appsignal.config.revision" => revision, "appsignal.config.language_integration" => "ruby", "appsignal.config.app_path" => Dir.pwd, "host.name" => Socket.gethostname, ) # Customize the service name c.service_name = "My service name" # Configure the OpenTelemetry HTTP exporter c.add_span_processor( OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new( OpenTelemetry::Exporter::OTLP::Exporter.new( :endpoint => "http://localhost:8099/v1/traces", :compression => "none" ) ) ) # Activate all OpenTelemetry instrumentations # Use when using the 'opentelemetry-instrumentation-all' gem c.use_all end

Customize the service name in OpenTelemetry

Choose a service name for your app that makes each component or service easily recognizable. This service name will be used to group namespaces by service.

The resulting namespaces are formatted like so: <service name>/<namespace>

If the service name is "My service name" and the namespace is "admin", the resulting namespace on AppSignal.com becomes: "My service namespace/admin"

The important part of naming is that it makes sense to you and your team.

Some examples of service names:

  • Rails server
  • Sidekiq worker
  • Authentication API
  • Loadbalancer
  • Or whatever internal name each service has in your infrastructure

Below is an example of how to configure it in Ruby. See the previous steps code example for the language your app is using on where to modify the service_name field or service.name attribute.

Ruby
# opentelemetry.rb # ... OpenTelemetry::SDK.configure do |c| # Example: c.service_name = "My service name" # If you have Sidekiq in your app, you may want to configure it like so: c.service_name = if Sidekiq.server? "Sidekiq worker" else "Web server" end # ... end

Customize the exporter

When OpenTelemetry is instrumenting your application, it's necessary to export the data to our collector so that it can then be sent to our API.

In the code examples shown earlier, an OpenTelemetry HTTP traces and metrics exporter are already configured to send data to this endpoint on the collector:

  • Traces: http://localhost:8099/v1/traces
  • Metrics: http://localhost:8099/v1/metrics

Port 8099 is different than OpenTelemetry's default port, so it's required to specify to export data to our collector. We recommend using the collector's default 8099 port, but if this is not possible, the port can be changed with the http_port config option. Ensure that you also update the ports definition in the Install the AppSignal collector step for the Docker command if you've chosen to install the collector using the Docker image.

Most OpenTelemetry exporter packages automatically set the export path to /v1/traces for traces and /v1/metrics for metrics, but for some languages (like Python and Node.js) it may be needed to specify the entire path.

If your app is using the collector's Docker container, change localhost to the container's (host) name to send the data to the correct host on the internal network, like:

  • Traces: http://appsignal-collector:8099/v1/traces
  • Metrics: http://appsignal-collector:8099/v1/metrics

Test the app!

Now that all the components are connected, start your app and test if you see data arrive in AppSignal. Check the "Errors > Issue list" and "Performance > Traces" page specifically.

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!