Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sentry-opentelemetry/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ eval_gemfile "../Gemfile.dev"
gemspec

gem "opentelemetry-sdk"
gem "opentelemetry-exporter-otlp" unless RUBY_PLATFORM == "java"
gem "opentelemetry-instrumentation-rails"

gem "sentry-ruby", path: "../sentry-ruby"
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ module OTLP
class Configuration
attr_accessor :enabled
attr_accessor :setup_otlp_traces_exporter
attr_accessor :collector_url
attr_accessor :setup_propagator

def initialize
@enabled = false
@setup_otlp_traces_exporter = true
@collector_url = nil
@setup_propagator = true
end
end
Expand Down
21 changes: 13 additions & 8 deletions sentry-opentelemetry/lib/sentry/opentelemetry/otlp_setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module OTLPSetup
class << self
def setup(config)
@dsn = config.dsn
@collector_url = config.otlp.collector_url
@sdk_logger = config.sdk_logger
log_debug("[OTLP] Setting up OTLP integration")

Expand Down Expand Up @@ -39,7 +40,7 @@ def setup_external_propagation_context
end

def setup_otlp_exporter
return unless @dsn
return unless @dsn || @collector_url

log_debug("[OTLP] Setting up OTLP exporter")

Expand All @@ -51,15 +52,19 @@ def setup_otlp_exporter
return
end

endpoint = "#{@dsn.server}#{@dsn.otlp_traces_endpoint}"
auth_header = @dsn.generate_auth_header(client: USER_AGENT)
exporter = if @collector_url
endpoint = @collector_url
log_debug("[OTLP] Sending traces to collector at #{endpoint}")

log_debug("[OTLP] Sending traces to #{endpoint}")
::OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: endpoint)
else
endpoint = "#{@dsn.server}#{@dsn.otlp_traces_endpoint}"
auth_header = @dsn.generate_auth_header(client: USER_AGENT)
headers = { "X-Sentry-Auth" => auth_header }
log_debug("[OTLP] Sending traces to #{endpoint}")

exporter = ::OpenTelemetry::Exporter::OTLP::Exporter.new(
endpoint: endpoint,
headers: { "X-Sentry-Auth" => auth_header }
)
::OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: endpoint, headers: headers)
end

span_processor = ::OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(exporter)
::OpenTelemetry.tracer_provider.add_span_processor(span_processor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
it "sets default values" do
expect(subject.enabled).to eq(false)
expect(subject.setup_otlp_traces_exporter).to eq(true)
expect(subject.collector_url).to be_nil
expect(subject.setup_propagator).to eq(true)
end
end
Expand All @@ -17,6 +18,11 @@
expect(subject.enabled).to eq(true)
end

it "allows setting collector_url" do
subject.collector_url = "http://localhost:4318/v1/traces"
expect(subject.collector_url).to eq("http://localhost:4318/v1/traces")
end

it "allows setting setup_otlp_traces_exporter" do
subject.setup_otlp_traces_exporter = false
expect(subject.setup_otlp_traces_exporter).to eq(false)
Expand Down
71 changes: 67 additions & 4 deletions sentry-opentelemetry/spec/sentry/opentelemetry/otlp_setup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
perform_otel_setup
end

def span_processors
::OpenTelemetry.tracer_provider.instance_variable_get(:@span_processors)
end

describe '.setup' do
context 'with setup_propagator enabled' do
before do
Expand All @@ -23,21 +27,80 @@
end
end

context 'with setup_otlp_traces_exporter enabled' do
before do
perform_basic_setup do |config|
config.otlp.enabled = true
context 'with setup_otlp_traces_exporter enabled', unless: RUBY_PLATFORM == "java" do
context 'without collector_url (default DSN-based endpoint)' do
before do
perform_basic_setup do |config|
config.otlp.enabled = true
config.otlp.setup_otlp_traces_exporter = true
end
end

it 'creates the exporter with the DSN endpoint and auth headers' do
dsn = Sentry.configuration.dsn
expected_endpoint = "#{dsn.server}#{dsn.otlp_traces_endpoint}"

expect(::OpenTelemetry::Exporter::OTLP::Exporter).to receive(:new)
.with(endpoint: expected_endpoint, headers: hash_including("X-Sentry-Auth"))
.and_call_original

described_class.setup(Sentry.configuration)

expect(span_processors.last).to be_a(::OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor)
end
end

context 'with collector_url' do
let(:collector_url) { "http://localhost:4318/v1/traces" }

before do
perform_basic_setup do |config|
config.otlp.enabled = true
config.otlp.setup_otlp_traces_exporter = true
config.otlp.collector_url = collector_url
end
end

it 'creates the exporter with the collector endpoint' do
expect(::OpenTelemetry::Exporter::OTLP::Exporter).to receive(:new)
.with(endpoint: collector_url)
.and_call_original

described_class.setup(Sentry.configuration)

expect(span_processors.last).to be_a(::OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor)
end
end

it 'logs a warning when opentelemetry-exporter-otlp is not installed' do
perform_basic_setup do |config|
config.otlp.enabled = true
config.otlp.setup_otlp_traces_exporter = true
end

allow_any_instance_of(Object).to receive(:require).with("opentelemetry/exporter/otlp").and_raise(LoadError)

expect(Sentry.configuration.sdk_logger).to receive(:warn).with(/opentelemetry-exporter-otlp gem is not installed/)
described_class.setup(Sentry.configuration)
end
end

context 'with setup_otlp_traces_exporter disabled' do
before do
perform_basic_setup do |config|
config.otlp.enabled = true
config.otlp.setup_otlp_traces_exporter = false
end
end

it 'does not add a span processor' do
processors_before = span_processors.length
described_class.setup(Sentry.configuration)

expect(span_processors.length).to eq(processors_before)
end
end

context 'with external propagation context' do
before do
perform_basic_setup do |config|
Expand Down
Loading