The `Labkit::Tracing` module provides distributed tracing functionality for Ruby applications using the OpenTracing or OpenTelemetry standards. It enables you to trace requests across multiple services and components, helping you understand application performance and debug issues in distributed systems.
The `Labkit::Tracing` module provides distributed tracing functionality for Ruby applications using the OpenTelemetry standard. It enables you to trace requests across multiple services and components, helping you understand application performance and debug issues in distributed systems.
## Overview
Distributed tracing allows you to track requests as they flow through your application and external services. The tracing module integrates with OpenTelemetry (OTLP) and Jaeger (OpenTracing) backends, and provides automatic instrumentation for:
Distributed tracing allows you to track requests as they flow through your application and external services. The tracing module integrates with OpenTelemetry (OTLP) backends, and provides automatic instrumentation for:
- HTTP requests (Rack/Rails)
- gRPC calls (client and server)
@@ -12,19 +12,6 @@ Distributed tracing allows you to track requests as they flow through your appli
Labkit-Ruby supports both OpenTracing and OpenTelemetry protocols. The library automatically detects which protocol to use based on the `GITLAB_TRACING` connection string and provides a unified API that works seamlessly with both.
**Note:** OpenTracing is [archived and deprecated](https://opentracing.io/). OpenTelemetry is the recommended tracing protocol for new projects. Labkit-Ruby maintains OpenTracing support for backward compatibility.
### Protocol Selection
-**OpenTelemetry** (Recommended): Use `otlp://` prefix in connection string
-**OpenTracing** (Deprecated): Use `opentracing://` prefix in connection string
All public APIs (`Labkit::Tracing.with_tracing`, `Labkit::Tracing.sampled?`, etc.) work identically regardless of the protocol used.
## Configuration
Tracing is controlled via environment variables:
@@ -33,24 +20,15 @@ Tracing is controlled via environment variables:
**`GITLAB_TRACING`** - Connection string for the tracing backend
Format: `opentracing://<driver>?<options>` or `otlp://<host:port>?<options>`
Format: `otlp://<host:port>?<options>`
Example:
```bash
# OpenTelemetry with HTTP endpoint (Recommended)
# OpenTelemetry with HTTP endpoint
export GITLAB_TRACING="otlp://localhost:4318"
# Console exporter for development/testing (outputs to stdout)
export GITLAB_TRACING="otlp://console"
# Jaeger with UDP endpoint (OpenTracing - Deprecated)
# Factory.create_tracer configures the tracer globally by setting
# OpenTelemetry.tracer_provider. No additional setup needed
end
```
#### With Configuration Block (Recommended for OpenTelemetry)
#### With Configuration Block (Recommended)
For OpenTelemetry (OTLP) connections, you can customize the SDK while preserving GITLAB_TRACING settings:
You can customize the OpenTelemetry SDK while preserving GITLAB_TRACING settings:
```ruby
# In your application initializer (e.g., config/initializers/tracing.rb)
@@ -229,13 +174,8 @@ end
- Full access to OpenTelemetry SDK features (instrumentation, span processors, resources)
- Configuration block is optional
**Note:** Configuration blocks only work with OpenTelemetry connections (`otlp://`). They are ignored for OpenTracing connections (`opentracing://`) with a warning.
**What happens without initialization:**
-**OpenTelemetry (OTLP):** Falls back to a no-op tracer (the default `ProxyTracerProvider` is detected and skipped)
-**OpenTracing (Jaeger):** Uses the default no-op tracer
In both cases, spans are created but not exported, allowing your application to run safely while producing no trace data.
Falls back to a no-op tracer (the default `ProxyTracerProvider` is detected and skipped). Spans are created but not exported, allowing your application to run safely while producing no trace data.
### Manual Span Creation
@@ -257,7 +197,7 @@ end
With parent span context:
```ruby
# Get the current active span (works with both OpenTracing and OpenTelemetry)
@@ -288,25 +228,6 @@ When using `Factory.create_tracer` with a configuration block:
**Important:** Calling `Factory.create_tracer` multiple times will reconfigure the global OpenTelemetry tracer provider each time. The last call wins. This is generally safe but **should be avoided** - initialize tracing once during application startup.
2.**No code changes required** - All Labkit tracing APIs (`Labkit::Tracing.with_tracing`, `Labkit::Tracing.sampled?`, etc.) work identically with both protocols.
That's it! The migration is transparent thanks to Labkit's protocol-agnostic API.
## Deprecations
-**OpenTracing Protocol** - The OpenTracing project is archived and deprecated. Use OpenTelemetry (`otlp://` connection string) for new projects. OpenTracing support (`opentracing://` connection string) is maintained for backward compatibility during migration.
-**`Labkit::Tracing::GRPCInterceptor`** - Deprecated, use `Labkit::Tracing::GRPC::ClientInterceptor` instead
## Example: Complete Setup
@@ -658,7 +558,7 @@ If you've confirmed initialization is correct:
2. Check for tracer creation errors in logs (warnings are emitted on failure)
3. Verify the Jaeger agent/collector is reachable
3. Verify the OTLP collector is reachable
### Missing Spans
@@ -670,7 +570,7 @@ If you've confirmed initialization is correct:
### Middleware Works But No Traces Appear
If your application runs without errors but you don't see traces in your backend (OTLP collector, Jaeger, etc.):
If your application runs without errors but you don't see traces in your backend (OTLP collector):
**1. Verify you called `Factory.create_tracer` in your initializer:**
@@ -683,7 +583,7 @@ if Labkit::Tracing.enabled?
end
```
**2. For OpenTelemetry (OTLP), verify the tracer provider is initialized:**
Without calling `Factory.create_tracer`, LabKit uses a no-op tracer that creates span objects for instrumentation but doesn't export them to any backend. This design prevents crashes when tracing is misconfigured, but means no trace data is collected.
@@ -707,7 +599,7 @@ Without calling `Factory.create_tracer`, LabKit uses a no-op tracer that creates