The solarwinds_apm
gem starting from version 6.0.0 is an OpenTelemetry Ruby distribution. It provides automatic instrumentation and custom SolarWinds Observability features for Ruby applications.
Only Linux is supported, the gem will go into no-op mode on other platforms. MRI Ruby version 3 or above is required. The SolarWinds Observability documentation website has details on the supported platforms and system dependencies.
See CONTRIBUTING.md for how to build for development.
solarwinds_apm
is available on Rubygems. Install with:
gem install solarwinds_apm
Or add to the end of your application Gemfile and run bundle install
if managing gems with Bundler:
# application dependencies, eg
# gem "rails", "~> 7.0.5", ">= 7.0.5.1"
# end of Gemfile
gem 'solarwinds_apm'
Ideally all application gems are required by Bundler.require
, which guarantees loading in the order they appear in the Gemfile. If Bundler.require
does not require all application gems, call require 'solarwinds_apm'
after all gems that need instrumentation are loaded.
The only required configuration is the service key, which can be set in the SW_APM_SERVICE_KEY
environment variable or in the configuration file as :service_key
. See CONFIGURATION.md for the complete reference.
solarwinds_apm
supports the standard OpenTelemetry API for tracing and includes a helper to ease its use in manual instrumentation. Additionally, a set of SolarWindsAPM APIs are provided for features specific to SolarWinds Observability.
This gem installs the dependencies needed to use the OTel API and initializes the globally-registered TracerProvider
. So the "Setup" and "Acquiring a Tracer" sections of the OTel Ruby Manual Instrumentation should be skipped. Instead, your application code should acquire a Tracer
from the global TracerProvider
as follows.
The Tracer
object is determined by the service name, which is the portion after the colon (:
) set in the SW_APM_SERVICE_KEY
or :service_key
configuration. The service name is also automatically set into the OTEL_SERVICE_NAME
environment variable which can be referenced as shown below. The Tracer
object can then be used as described in the OTel Ruby documentation.
The example below shows how the standard OTel API to create a span and get the current span can be used in an application where solarwinds_apm
has been loaded. See also the convenience wrapper for in_span provided by the SolarWindsAPM API:
# acquire the tracer
MyAppTracer = ::OpenTelemetry.tracer_provider.tracer(ENV['OTEL_SERVICE_NAME'])
# create a new span
MyAppTracer.in_span('new.span', attributes: {'key1' => 'value1', 'key2' => 'value2'}) do |span|
# do things
end
# work with the current span
current_span = ::OpenTelemetry::Trace.current_span
# current_span.add_attributes
# current_span.add_event
# current_span.record_exception
Note that if OpenTelemetry::SDK.configure
is used to set up a TracerProvider
, it will not be configured with our distribution's customizations and manual instrumentation made with its Tracer
object will not be reported to SolarWinds Observability.
Several convenience and vendor-specific APIs are availabe to an application where solarwinds_apm
has been loaded, below is a quick overview of the features provided. The full reference can be found at the RubyDoc page for this gem.
This method acquires the correct Tracer
so a new span can be created in a single call, below is a simple Rails controller example:
class StaticController < ApplicationController
def home
SolarWindsAPM::API.in_span('custom_span') do |span|
# do things
end
end
end
The current_trace_info
method returns a TraceInfo
object containing string representations of the current trace context that can be used in logging or manual propagation of context. This is a convenience method that wraps the OTel API ::OpenTelemetry::Trace.current_span
.
trace = SolarWindsAPM::API.current_trace_info
trace.tracestring # 00-7435a9fe510ae4533414d425dadf4e18-49e60702469db05f-01
trace.trace_id # 7435a9fe510ae4533414d425dadf4e18
trace.span_id # 49e60702469db05f
trace.trace_flags # 01
On startup, this library initializes and maintains a connection to a SolarWinds Observability collector, and receives settings used for making tracing decisions. This process can take up to a few seconds depending on the connection. If the application receives requests before initialization has completed, these requests will not be traced. While this is not critical for long-running server processes, it might be a problem for short-running apps such as cron jobs or CLI apps.
A call to the solarwinds_ready
method allows the application to block until initialization has completed and the library is ready for tracing. The method accepts an optional timeout parameter in milliseconds.
SolarWindsAPM::API.solarwinds_ready(wait_milliseconds=3000)
By default, transaction names are constructed based on attributes such as the requested route in the server framework, or the span name. If this name is not descriptive enough, you can override it with a custom one. If multiple transaction names are set on the same trace, the last transaction name is used.
result = SolarWindsAPM::API.set_transaction_name('my-custom-trace-name')
Service metrics are automatically collected by this library. In addition, the following methods support sending two types of custom metrics:
increment_metric
- counts the number of times something has occurredsummary_metric
- a specific value for the default count of 1, or the sum of values if count > 1
The metrics submitted are aggregated by metric name and tag(s), then sent every 60 seconds.
SolarWindsAPM::API.increment_metric('loop.iteration')
SolarWindsAPM::API.summary_metric('sleep.time', 5000)