Verified Commit 3d81966c authored by Hercules Merscher's avatar Hercules Merscher 🌴
Browse files

fix: README -- removing docs for deprecated opentracing impl.

parent ae0dc952
Loading
Loading
Loading
Loading
+23 −133
Original line number Diff line number Diff line
# Labkit::Tracing

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
- External HTTP requests
- Rails components (ActiveRecord, ActionView, ActiveSupport)

## Protocol Support

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)
export GITLAB_TRACING="opentracing://jaeger?udp_endpoint=localhost:6831"

# Jaeger with HTTP endpoint (OpenTracing - Deprecated)
export GITLAB_TRACING="opentracing://jaeger?http_endpoint=https://jaeger.example.com:14268/api/traces"

# Jaeger with sampling configuration (OpenTracing - Deprecated)
export GITLAB_TRACING="opentracing://jaeger?udp_endpoint=localhost:6831&sampler=probabilistic&sampler_param=0.1"
```

**Important: Initialization Required**
@@ -60,11 +38,9 @@ Setting `GITLAB_TRACING` alone is not sufficient to collect traces. You must exp
Without calling `Factory.create_tracer`:
- Your application runs safely without errors
- Instrumentation middleware creates span objects
- **No trace data is exported** to your backend (OTLP collector or Jaeger)
- **No trace data is exported** to your backend (OTLP collector)
- A no-op tracer is used internally

This applies to both OpenTelemetry (`otlp://...`) and OpenTracing (`opentracing://jaeger...`) connection strings.

### Optional Configuration

**`GITLAB_TRACING_URL`** - Template URL for linking to trace views
@@ -75,7 +51,7 @@ Supports placeholders:

Example:
```bash
export GITLAB_TRACING_URL="https://jaeger.example.com/trace/{{ correlation_id }}?service={{ service }}"
export GITLAB_TRACING_URL="https://tracing.example.com/trace/{{ correlation_id }}?service={{ service }}"
```

**`GITLAB_TRACING_INCLUDE_STACKTRACE`** - Comma-separated list of operation name prefixes to include stack traces
@@ -85,9 +61,9 @@ Example:
export GITLAB_TRACING_INCLUDE_STACKTRACE="redis,active_record"
```

## OTLP Configuration Options
## Connection String Configuration

When using OpenTelemetry (OTLP) as the tracing backend, the following connection string formats and query parameters are supported:
The following connection string formats and query parameters are supported:

### Endpoints

@@ -134,35 +110,6 @@ export GITLAB_TRACING="otlp://user:pass@collector.prod.example.com:4318/v1/trace
export GITLAB_TRACING="otlp://console?sampler=const&sampler_param=0"
```

## Jaeger Configuration Options

When using Jaeger as the tracing backend, the following query parameters are supported:

### Endpoints

- **`udp_endpoint`** - Jaeger agent UDP endpoint (default port: 6831)
  - Example: `udp_endpoint=localhost:6831`
- **`http_endpoint`** - Jaeger collector HTTP endpoint
  - Example: `http_endpoint=https://jaeger.example.com:14268/api/traces`
  - Supports basic authentication: `http_endpoint=https://user:password@jaeger.example.com/api/traces`

### Sampling

- **`sampler`** - Sampling strategy (`probabilistic` or `const`)
  - `probabilistic` - Sample a percentage of traces (default: 0.1%)
  - `const` - Sample all traces (when `sampler_param=1`) or none (when `sampler_param=0`)

- **`sampler_param`** - Parameter for the sampler
  - For `probabilistic`: rate between 0.0 and 1.0 (e.g., `0.1` = 10%)
  - For `const`: `1` (sample all) or `0` (sample none)

- **`service_name`** - Override the service name for this tracer

Example:
```bash
export GITLAB_TRACING="opentracing://jaeger?udp_endpoint=localhost:6831&sampler=probabilistic&sampler_param=0.01"
```

## Usage

### Checking if Tracing is Enabled
@@ -187,16 +134,14 @@ if Labkit::Tracing.enabled?
  # REQUIRED: Create the tracer to actually collect traces
  Labkit::Tracing::Factory.create_tracer("my-service", ENV["GITLAB_TRACING"])

  # Factory.create_tracer configures the tracer globally for both:
  # - OpenTelemetry/OTLP: Sets OpenTelemetry.tracer_provider
  # - OpenTracing/Jaeger: Sets OpenTracing.global_tracer
  # No additional setup needed
  # 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)
# Get the current active span
parent_span = Labkit::Tracing::TracingUtils.active_span

Labkit::Tracing.with_tracing(
@@ -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.

**Example showing precedence:**
```ruby
# GITLAB_TRACING="otlp://localhost:4318?sampler=probabilistic&sampler_param=0.01"

Labkit::Tracing::Factory.create_tracer("api-service", ENV["GITLAB_TRACING"]) do |c|
  # These settings are ADDED to GITLAB_TRACING configuration
  c.use 'OpenTelemetry::Instrumentation::Rails'

  # Resource attributes are MERGED
  c.resource = c.resource.merge(
    OpenTelemetry::SDK::Resources::Resource.create('env' => 'production')
  )

  # Sampler from GITLAB_TRACING (probabilistic 1%) is preserved
  # Exporter endpoint (localhost:4318) is preserved
  # Service name ('api-service') is preserved unless you override it
end
```

### Getting Trace URLs

Generate a URL to view the current trace in your tracing UI:
@@ -314,7 +235,7 @@ Generate a URL to view the current trace in your tracing UI:
```ruby
if Labkit::Tracing.tracing_url_enabled?
  url = Labkit::Tracing.tracing_url("my-service")
  # Returns: https://jaeger.example.com/trace/abc123?service=my-service
  # Returns: https://tracing.example.com/trace/abc123?service=my-service
end
```

@@ -455,10 +376,9 @@ Automatically traces:
### Core Components

- **`Labkit::Tracing`** - Main module with configuration and utility methods
- **`Labkit::Tracing::Factory`** - Creates and configures tracer instances (supports both OpenTracing and OpenTelemetry)
- **`Labkit::Tracing::JaegerFactory`** - Jaeger-specific tracer configuration (OpenTracing)
- **`Labkit::Tracing::Factory`** - Creates and configures tracer instances
- **`Labkit::Tracing::OpenTelemetryFactory`** - OpenTelemetry-specific tracer configuration
- **`Labkit::Tracing::TracingUtils`** - Protocol-agnostic utilities for span management (abstracts OpenTracing and OpenTelemetry APIs)
- **`Labkit::Tracing::TracingUtils`** - Utilities for span management
- **`Labkit::Tracing::AbstractInstrumenter`** - Base class for ActiveSupport::Notifications instrumenters

### Instrumentation Pattern
@@ -514,9 +434,9 @@ if Labkit::Tracing.sampled?
end
```

### Flush Interval
### Batch Span Processing

The Jaeger reporter flushes spans every 5 seconds (configurable via `FLUSH_INTERVAL` constant) to prevent UDP packet overflow.
Spans are batched and exported to the OTLP endpoint at regular intervals to optimize performance and network usage.

## Integration with Correlation

@@ -528,28 +448,8 @@ correlation_id = Labkit::Correlation::CorrelationId.current_id
# This ID appears in both logs and traces
```

## Migrating from OpenTracing to OpenTelemetry

To migrate from OpenTracing to OpenTelemetry:

1. **Update the connection string** - Change from `opentracing://` to `otlp://`:
   ```bash
   # Before
   export GITLAB_TRACING="opentracing://jaeger?udp_endpoint=localhost:6831"

   # After
   export GITLAB_TRACING="otlp://localhost:4318"
   ```

2. **No code changes required** - All Labkit tracing APIs (`Labkit::Tracing.with_tracing`, `Labkit::Tracing.sampled?`, etc.) work identically with both protocols.

3. **Update backend configuration** - Ensure your tracing backend (Jaeger, etc.) supports OpenTelemetry OTLP protocol.

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:**
**2. Verify the tracer provider is initialized:**

```ruby
OpenTelemetry.tracer_provider.class
@@ -691,14 +591,6 @@ OpenTelemetry.tracer_provider.class
# Problem:  OpenTelemetry::Internal::ProxyTracerProvider (means Factory.create_tracer wasn't called)
```

**3. For OpenTracing (Jaeger), verify the global tracer is set:**

```ruby
OpenTracing.global_tracer.class
# Expected: Jaeger::Client::Tracer
# Problem:  OpenTracing::Tracer (means tracer wasn't initialized/set)
```

**Why this happens:**

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

1. Reduce sampling rate:
   ```bash
   export GITLAB_TRACING="opentracing://jaeger?udp_endpoint=localhost:6831&sampler=probabilistic&sampler_param=0.001"
   export GITLAB_TRACING="otlp://localhost:4318?sampler=probabilistic&sampler_param=0.001"
   ```

2. Disable stack traces or limit to specific operations:
@@ -719,6 +611,4 @@ Without calling `Factory.create_tracer`, LabKit uses a no-op tracer that creates

- [OpenTelemetry Documentation](https://opentelemetry.io/docs/languages/ruby/)
- [OpenTelemetry Protocol (OTLP) Specification](https://opentelemetry.io/docs/specs/otlp/)
- [OpenTracing Specification](https://opentracing.io/specification/)
- [Jaeger Documentation](https://www.jaegertracing.io/docs/)
- [Rails Instrumentation Guide](https://guides.rubyonrails.org/active_support_instrumentation.html)