OpenTelemetry Tracing API for Ruby
TIP
This document teaches how to use OpenTelemetry Ruby API. To learn how to install and configure OpenTelemetry Ruby SDK, see Getting started with OpenTelemetry Ruby.
Installation
OpenTelemetry-Ruby is the Ruby implementation of OpenTelemetry. It provides OpenTelemetry Tracing API which you can use to instrument your application with OpenTelemetry traces.
gem 'opentelemetry'
Quickstart
Step 1. Let's instrument the following function:
def create_user(name, email)
User.create(name: name, email: email)
end
Step 2. Wrap the operation with a span:
require 'opentelemetry'
tracer = OpenTelemetry.tracer_provider.tracer('my_app_or_gem', '1.0.0')
def create_user(name, email)
tracer.in_span('insert-user', kind: :server) do |span|
User.create(name: name, email: email)
end
end
Step 3. Record contextual information with attributes:
def create_user(name, email)
tracer.in_span('insert-user', kind: :server) do |span|
if span.recording?
span.set_attribute('enduser.name', name)
span.set_attribute('enduser.email', email)
end
User.create(name: name, email: email)
end
end
And that's it! You don't have to manually record exceptions, because tracer.in_span
does that automatically for you.
Tracer
To start creating spans, you need a tracer. You can create a tracer by providing the name and version of the library/application doing the instrumentation:
require 'opentelemetry'
tracer = OpenTelemetry.tracer_provider.tracer('my_app_or_gem', '1.0.0')
You can have as many tracers as you want, but usually you need only one tracer for an app or a library. Later, you can use tracer names to identify the instrumentation that produces the spans.
Creating spans
Once you have a tracer, creating spans is easy:
# Create a span with name "operation-name" and kind="server".
tracer.in_span('operation-name', kind: :server) do |span|
do_some_work
end
Internally, in_span
helper creates a span, resques and records any exceptions, sets the span status code, and finishes the span:
# Create a span.
span = tracer.start_span('operation-name', kind: :server)
# Activate the span in the current context.
OpenTelemetry::Trace.with_span(span) do |span|
do_some_work
rescue Exception => e
span.record_exception(e)
span.status = OpenTelemetry::Trace::Status.error("Unhandled exception of type: #{e.class}")
raise e
ensure
span.finish
end
Adding span attributes
To record contextual information, you can annotate spans with attributes. For example, an HTTP endpoint may have such attributes as http.method = GET
and http.route = /projects/:id
.
# To avoid expensive computations, check that span is recording
# before setting any attributes.
if span.recording?
span.set_attribute('http.method", 'GET')
span.set_attribute('http.route", '/projects/:id')
end
You can name attributes as you want, but for common operations you should use semantic attributes convention.
Adding span events
You can annotate spans with events, for example, you can use events to record log messages:
span.add_event(
name: 'log',
attributes: {
'log.severity' => 'error',
'log.message' => 'User not found',
'enduser.id' => '123'
}
)
Setting status code
You can set error
status code to indicate that the operation contains an error:
rescue Exception => e
span.status = OpenTelemetry::Trace::Status.error(e.to_s)
end
Recording exceptions
OpenTelemetry provides a shortcut to record exceptions which is usually used together with status
:
rescue Exception => e
# Record the exception and update the span status.
span.record_exception(e)
span.status = OpenTelemetry::Trace::Status.error(e.to_s)
end
Please note that tracer.in_span
automatically rescues and records exceptions for you.
Context
OpenTelemetry stores the active span in a context and saves the context in a thread-local storage. You can nest contexts inside each other and OpenTelemetry will automatically activate the parent span context when you end the span.
tracer.in_span
sets the active span for you, but you can also activate the span manually:
OpenTelemetry::Trace.with_span(main) do |span|
do_some_work
end
To get the current span:
require 'opentelemetry'
span = OpenTelemetry::Trace.current_span
OpenTelemetry APM
Uptrace is an open source APM for OpenTelemetry that supports distributed tracing, metrics, and logs. You can use it to monitor applications and troubleshoot issues.
Uptrace comes with an intuitive query builder, rich dashboards, alerting rules, notifications, and integrations for most languages and frameworks.
Uptrace can process billions of spans and metrics on a single server and allows you to monitor your applications at 10x lower cost.
In just a few minutes, you can try Uptrace by visiting the cloud demo (no login required) or running it locally with Docker. The source code is available on GitHub.