Skip to content

Commit 844476b

Browse files
feat: metrics reporter for Jaeger collector exporter (#1271)
* tidy: move tests directory to match lib structure * feat: add support for a metrics reporter * fix: remove duplicated test * chore: switch to rspec mocks Co-authored-by: Francis Bogsanyi <[email protected]>
1 parent d3990c6 commit 844476b

File tree

6 files changed

+64
-2
lines changed

6 files changed

+64
-2
lines changed

exporter/jaeger/lib/opentelemetry/exporter/jaeger/collector_exporter.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ def initialize(endpoint: ENV.fetch('OTEL_EXPORTER_JAEGER_ENDPOINT', 'http://loca
2929
username: ENV['OTEL_EXPORTER_JAEGER_USER'],
3030
password: ENV['OTEL_EXPORTER_JAEGER_PASSWORD'],
3131
timeout: ENV.fetch('OTEL_EXPORTER_JAEGER_TIMEOUT', 10),
32-
ssl_verify_mode: CollectorExporter.ssl_verify_mode)
32+
ssl_verify_mode: CollectorExporter.ssl_verify_mode,
33+
metrics_reporter: nil)
3334
raise ArgumentError, "invalid url for Jaeger::CollectorExporter #{endpoint}" unless OpenTelemetry::Common::Utilities.valid_url?(endpoint)
3435
raise ArgumentError, 'username and password should either both be nil or both be set' if username.nil? != password.nil?
3536

@@ -41,6 +42,7 @@ def initialize(endpoint: ENV.fetch('OTEL_EXPORTER_JAEGER_ENDPOINT', 'http://loca
4142
@transport.add_headers(auth_header)
4243
end
4344
@serializer = ::Thrift::Serializer.new
45+
@metrics_reporter = metrics_reporter || OpenTelemetry::SDK::Trace::Export::MetricsReporter
4446
@shutdown = false
4547
end
4648

@@ -59,10 +61,13 @@ def export(span_data, timeout: nil)
5961
end
6062

6163
OpenTelemetry::Common::Utilities.untraced do
62-
@transport.flush
64+
measure_request_duration do
65+
@transport.flush
66+
end
6367
end
6468
SUCCESS
6569
rescue StandardError => e
70+
@metrics_reporter.add_to_counter('otel.jaeger_exporter.failure', labels: { 'reason' => e.class.to_s })
6671
OpenTelemetry.handle_error(exception: e, message: 'unexpected error in Jaeger::CollectorExporter#export')
6772
FAILURE
6873
end
@@ -95,6 +100,15 @@ def encoded_batches(span_data)
95100
Thrift::Batch.new('process' => process, 'spans' => spans)
96101
end
97102
end
103+
104+
def measure_request_duration
105+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
106+
yield
107+
ensure
108+
stop = Process.clock_gettime(Process::CLOCK_MONOTONIC)
109+
duration_ms = 1000.0 * (stop - start)
110+
@metrics_reporter.record_value('otel.jaeger_exporter.request_duration', value: duration_ms)
111+
end
98112
end
99113
end
100114
end

exporter/jaeger/opentelemetry-exporter-jaeger.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
3737
spec.add_development_dependency 'minitest', '~> 5.0'
3838
spec.add_development_dependency 'opentelemetry-test-helpers'
3939
spec.add_development_dependency 'rake', '~> 12.0'
40+
spec.add_development_dependency 'rspec-mocks'
4041
spec.add_development_dependency 'rubocop', '~> 0.73.0'
4142
spec.add_development_dependency 'simplecov', '~> 0.17'
4243
spec.add_development_dependency 'webmock', '~> 3.7.6'

exporter/jaeger/test/opentelemetry/exporters/jaeger/collector_exporter_test.rb renamed to exporter/jaeger/test/opentelemetry/exporter/jaeger/collector_exporter_test.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
DEFAULT_JAEGER_COLLECTOR_ENDPOINT = 'http://localhost:14268/api/traces'
99

1010
describe OpenTelemetry::Exporter::Jaeger::CollectorExporter do
11+
let(:metrics_reporter) { double }
12+
before(:each) do
13+
allow(metrics_reporter).to receive(:record_value)
14+
end
15+
1116
describe '#initialize' do
1217
it 'initializes with defaults' do
1318
exp = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new
@@ -175,5 +180,46 @@
175180
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::SUCCESS)
176181
assert_requested(stub_post)
177182
end
183+
184+
describe '#metrics_reporter' do
185+
it 'reports metrics for failures' do
186+
expect(metrics_reporter).to receive(:add_to_counter).with('otel.jaeger_exporter.failure', labels: { 'reason' => 'Thrift::TransportException' })
187+
188+
stub_post = stub_request(:post, DEFAULT_JAEGER_COLLECTOR_ENDPOINT).to_return(status: 500)
189+
exporter = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(
190+
metrics_reporter: metrics_reporter
191+
)
192+
span_data = create_span_data
193+
result = exporter.export([span_data])
194+
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::FAILURE)
195+
assert_requested(stub_post)
196+
end
197+
198+
it 'reports metrics for timeouts' do
199+
expect(metrics_reporter).to receive(:add_to_counter).with('otel.jaeger_exporter.failure', labels: { 'reason' => 'Net::OpenTimeout' })
200+
201+
stub_post = stub_request(:post, DEFAULT_JAEGER_COLLECTOR_ENDPOINT).to_timeout
202+
exporter = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(
203+
metrics_reporter: metrics_reporter
204+
)
205+
span_data = create_span_data
206+
result = exporter.export([span_data])
207+
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::FAILURE)
208+
assert_requested(stub_post)
209+
end
210+
211+
it 'records request duration' do
212+
expect(metrics_reporter).to receive(:record_value).with('otel.jaeger_exporter.request_duration', hash_including(value: kind_of(Float)))
213+
stub_post = stub_request(:post, DEFAULT_JAEGER_COLLECTOR_ENDPOINT).to_return(status: 200)
214+
215+
exporter = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(
216+
metrics_reporter: metrics_reporter
217+
)
218+
span_data = create_span_data
219+
result = exporter.export([span_data])
220+
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::SUCCESS)
221+
assert_requested(stub_post)
222+
end
223+
end
178224
end
179225
end

exporter/jaeger/test/test_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
require 'opentelemetry/exporter/jaeger'
1212
require 'minitest/autorun'
1313
require 'webmock/minitest'
14+
require 'rspec/mocks/minitest_integration'
1415

1516
def create_span_data(name: '', kind: nil, status: nil, parent_span_id: OpenTelemetry::Trace::INVALID_SPAN_ID,
1617
total_recorded_attributes: 0, total_recorded_events: 0, total_recorded_links: 0, start_timestamp: OpenTelemetry::TestHelpers.exportable_timestamp,

0 commit comments

Comments
 (0)