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

fix: Drop GRPC related content

parent 9ec9ac27
Loading
Loading
Loading
Loading
+0 −36
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@ The `Labkit::Tracing` module provides distributed tracing functionality for Ruby
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)
- Redis operations
- External HTTP requests
- Rails components (ActiveRecord, ActionView, ActiveSupport)
@@ -79,10 +78,6 @@ The following connection string formats and query parameters are supported:
  - Example with custom path: `otlp://localhost:4318/v1/traces`
  - Example with authentication: `otlp://user:password@collector.example.com:4318`

- **gRPC Endpoint** - OTLP gRPC collector endpoint (port 4317)
  - Example: `otlp://localhost:4317`
  - Note: Ruby SDK lacks native gRPC exporter, falls back to HTTP with protobuf encoding

- **Console Exporter** - Output spans to stdout (development/testing only)
  - Example: `otlp://console`
  - **Use Case**: Local development, debugging, automated testing
@@ -405,33 +400,6 @@ This automatically traces:
- Connection details (host, port, scheme)
- Sanitized command arguments (sensitive commands like AUTH and EVAL are masked)

### gRPC

#### Client-Side Instrumentation

```ruby
# Add to gRPC client configuration
interceptors = [Labkit::Tracing::GRPC::ClientInterceptor.instance]
stub = MyService::Stub.new(address, :this_channel_is_insecure, interceptors: interceptors)
```

Traces outgoing gRPC calls with:
- Method names
- gRPC call types (unary, client_stream, server_stream, bidi_stream)
- Automatic context propagation to downstream services

#### Server-Side Instrumentation

```ruby
# Add to gRPC server configuration
server = GRPC::RpcServer.new(interceptors: [Labkit::Tracing::GRPC::ServerInterceptor.new])
```

Traces incoming gRPC calls with:
- Method names
- gRPC call types
- Automatic context extraction from upstream services

### External HTTP Requests

**Note:** External HTTP instrumentation is automatically enabled when `GITLAB_TRACING` is set.
@@ -532,10 +500,6 @@ correlation_id = Labkit::Correlation::CorrelationId.current_id
# This ID appears in both logs and traces
```

## Deprecations

- **`Labkit::Tracing::GRPCInterceptor`** - Deprecated, use `Labkit::Tracing::GRPC::ClientInterceptor` instead

## Example: Complete Setup

### Development Environment with Console Exporter (Automatic)
+7 −42
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@ module Labkit
      # The default endpoint for OTLP HTTP exporter
      DEFAULT_HTTP_ENDPOINT = "http://localhost:4318/v1/traces"

      # The default endpoint for OTLP gRPC exporter
      DEFAULT_GRPC_ENDPOINT = "http://localhost:4317"

      class << self
        # @param service_name [String] The service name for the tracer
        # @param connection_string [String] The connection string (e.g., "otlp://localhost:4318")
@@ -38,7 +35,7 @@ module Labkit

          # Get sampler and exporter from GITLAB_TRACING
          sampler = get_sampler(options[:sampler], options[:sampler_param])
          exporter = get_exporter(options[:http_endpoint], options[:grpc_endpoint], options[:udp_endpoint], headers)
          exporter = get_exporter(options[:http_endpoint], options[:udp_endpoint], headers)

          # Build base resource
          base_resource = OpenTelemetry::SDK::Resources::Resource.create(
@@ -57,12 +54,10 @@ module Labkit
            :sampler,
            :sampler_param,
            :http_endpoint,
            :grpc_endpoint,
            :udp_endpoint,
            :strict_parsing,
            :debug,
            :service_name,
            :protocol
            :service_name
          )

          if extra_params.present?
@@ -152,9 +147,9 @@ module Labkit
        end

        def build_headers(options)
          return {} unless options&.key?(:http_endpoint) || options&.key?(:grpc_endpoint)
          return {} unless options&.key?(:http_endpoint)

          endpoint = options[:http_endpoint] || options[:grpc_endpoint]
          endpoint = options[:http_endpoint]
          return {} unless endpoint

          parsed = URI.parse(endpoint)
@@ -184,19 +179,15 @@ module Labkit
          end
        end

        def get_exporter(http_endpoint, grpc_endpoint, udp_endpoint, headers)
        def get_exporter(http_endpoint, udp_endpoint, headers)
          # OpenTelemetry doesn't support UDP, warn if specified
          # https://github.com/open-telemetry/opentelemetry-collector/discussions/6016
          warn "opentelemetry tracer: UDP endpoint not supported, ignoring udp_endpoint option" if udp_endpoint.present?

          # Check for console exporter (for development/testing)
          return get_console_exporter if http_endpoint&.include?("://console") || grpc_endpoint&.include?("://console")
          return get_console_exporter if http_endpoint&.include?("://console")

          if http_endpoint.present?
            get_http_exporter(http_endpoint, headers)
          elsif grpc_endpoint.present?
            get_grpc_exporter(grpc_endpoint, headers)
          end
          get_http_exporter(http_endpoint, headers) if http_endpoint.present?
        end

        def get_http_exporter(endpoint, headers)
@@ -206,25 +197,6 @@ module Labkit
          )
        end

        def get_grpc_exporter(endpoint, headers)
          # OpenTelemetry Ruby lacks native gRPC exporter support. Fall back to HTTP exporter with protobuf encoding,
          # which is the standard approach and compatible with most OTLP collectors that accept gRPC-style endpoints.
          warn "opentelemetry tracer: gRPC endpoint specified but gRPC exporter not available, using HTTP"

          parsed = URI.parse(endpoint)

          http_port = parsed.port == 4317 ? 4318 : parsed.port

          http_endpoint = URI::HTTP.build(
            scheme: parsed.scheme,
            host: parsed.host,
            port: http_port,
            path: "/v1/traces"
          ).to_s

          get_http_exporter(http_endpoint, headers)
        end

        def get_console_exporter
          OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter.new
        end
@@ -242,14 +214,7 @@ module Labkit
          end

          endpoint = build_otlp_endpoint(parsed)

          # Determine the endpoint type and set the appropriate option
          if parsed.port == 4317 || options[:protocol] == "grpc"
            options[:grpc_endpoint] = endpoint
          else
            # Default to HTTP (port 4318 or custom)
          options[:http_endpoint] = endpoint
          end

          options
        end
+5 −77
Original line number Diff line number Diff line
@@ -110,17 +110,6 @@ describe Labkit::Tracing::OpenTelemetryFactory do
      end
    end

    context "when handling grpc_endpoint configurations" do
      it_behaves_like "an opentelemetry tracer" do
        let(:tracer) { described_class.create_tracer(service_name, "otlp://localhost:4317") }
      end

      it "warns about gRPC not being available" do
        expect { described_class.create_tracer(service_name, "otlp://localhost:4317") }
          .to output(/gRPC endpoint specified but gRPC exporter not available/).to_stderr
      end
    end

    context "when handling udp_endpoint configurations" do
      it_behaves_like "an opentelemetry tracer" do
        let(:tracer) { described_class.create_tracer(service_name, "otlp://localhost:4318?udp_endpoint=localhost:6831") }
@@ -193,7 +182,7 @@ describe Labkit::Tracing::OpenTelemetryFactory do
      end

      it "does not configure an exporter when connection has no endpoint details" do
        exporter = described_class.send(:get_exporter, nil, nil, nil, {})
        exporter = described_class.send(:get_exporter, nil, nil, {})
        expect(exporter).to be_nil
      end
    end
@@ -208,18 +197,6 @@ describe Labkit::Tracing::OpenTelemetryFactory do
      end
    end

    context "when using grpc protocol parameter" do
      it_behaves_like "an opentelemetry tracer" do
        let(:tracer) { described_class.create_tracer(service_name, "otlp://collector:9090?protocol=grpc") }
      end

      it "sets grpc_endpoint when protocol=grpc is specified" do
        options = described_class.send(:parse_otlp_connection_string, "otlp://collector:9090?protocol=grpc")
        expect(options[:grpc_endpoint]).to eq("http://collector:9090")
        expect(options[:protocol]).to eq("grpc")
      end
    end

    context "when using console exporter" do
      it_behaves_like "an opentelemetry tracer" do
        let(:tracer) { described_class.create_tracer(service_name, "otlp://console") }
@@ -272,11 +249,6 @@ describe Labkit::Tracing::OpenTelemetryFactory do
      expect(options[:http_endpoint]).to eq("http://localhost:4318")
    end

    it "parses gRPC connections on port 4317" do
      options = described_class.send(:parse_otlp_connection_string, "otlp://localhost:4317")
      expect(options[:grpc_endpoint]).to eq("http://localhost:4317")
    end

    it "parses connections with path" do
      options = described_class.send(:parse_otlp_connection_string, "otlp://localhost:4318/v1/traces")
      expect(options[:http_endpoint]).to eq("http://localhost:4318/v1/traces")
@@ -293,12 +265,6 @@ describe Labkit::Tracing::OpenTelemetryFactory do
      expect(options[:sampler]).to eq("const")
      expect(options[:sampler_param]).to eq("1")
    end

    it "detects gRPC protocol from query parameter" do
      options = described_class.send(:parse_otlp_connection_string, "otlp://collector:9090?protocol=grpc")
      expect(options[:grpc_endpoint]).to eq("http://collector:9090")
      expect(options[:protocol]).to eq("grpc")
    end
  end

  describe ".build_headers" do
@@ -317,12 +283,6 @@ describe Labkit::Tracing::OpenTelemetryFactory do
      expected_auth = "Basic #{Base64.strict_encode64('user:pass')}"
      expect(headers).to eq({ "Authorization" => expected_auth })
    end

    it "handles grpc_endpoint with credentials" do
      headers = described_class.send(:build_headers, grpc_endpoint: "http://user:pass@localhost:4317")
      expected_auth = "Basic #{Base64.strict_encode64('user:pass')}"
      expect(headers).to eq({ "Authorization" => expected_auth })
    end
  end

  describe ".get_sampler" do
@@ -356,51 +316,19 @@ describe Labkit::Tracing::OpenTelemetryFactory do
    let(:headers) { {} }

    it "returns nil when no endpoint is provided" do
      exporter = described_class.send(:get_exporter, nil, nil, nil, headers)
      exporter = described_class.send(:get_exporter, nil, nil, headers)
      expect(exporter).to be_nil
    end

    it "returns HTTP exporter for http_endpoint" do
      exporter = described_class.send(:get_exporter, "http://localhost:4318", nil, nil, headers)
      exporter = described_class.send(:get_exporter, "http://localhost:4318", nil, headers)
      expect(exporter).to be_a(OpenTelemetry::Exporter::OTLP::Exporter)
    end

    it "warns and returns exporter for grpc_endpoint" do
      expect { described_class.send(:get_exporter, nil, "http://localhost:4317", nil, headers) }
        .to output(/gRPC endpoint specified/).to_stderr
    end

    it "converts standard gRPC port (4317) to HTTP port (4318)" do
      expect(OpenTelemetry::Exporter::OTLP::Exporter).to receive(:new).with(
        endpoint: "http://localhost:4318/v1/traces",
        headers: headers
      ).and_call_original

      described_class.send(:get_exporter, nil, "http://localhost:4317", nil, headers)
    end

    it "preserves custom gRPC ports without conversion" do
      expect(OpenTelemetry::Exporter::OTLP::Exporter).to receive(:new).with(
        endpoint: "http://localhost:9090/v1/traces",
        headers: headers
      ).and_call_original

      described_class.send(:get_exporter, nil, "http://localhost:9090", nil, headers)
    end

    it "warns about UDP not being supported" do
      expect { described_class.send(:get_exporter, nil, nil, "localhost:6831", headers) }
      expect { described_class.send(:get_exporter, nil, "localhost:6831", headers) }
        .to output(/UDP endpoint not supported/).to_stderr
    end

    it "prefers http_endpoint over grpc_endpoint" do
      expect(OpenTelemetry::Exporter::OTLP::Exporter).to receive(:new).with(
        endpoint: "http://localhost:4318",
        headers: headers
      ).and_call_original

      described_class.send(:get_exporter, "http://localhost:4318", "http://localhost:4317", nil, headers)
    end
  end

  describe "with config block" do
@@ -504,7 +432,7 @@ describe Labkit::Tracing::OpenTelemetryFactory do

  describe ".get_exporter for console" do
    it "creates console exporter for console endpoint" do
      exporter = described_class.send(:get_exporter, "http://console", nil, nil, {})
      exporter = described_class.send(:get_exporter, "http://console", nil, {})
      expect(exporter).to be_a(OpenTelemetry::SDK::Trace::Export::ConsoleSpanExporter)
    end
  end