Skip to content

Commit

Permalink
feat: metrics reporter for Jaeger collector exporter (#1271)
Browse files Browse the repository at this point in the history
* 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 <francis.bogsanyi@shopify.com>
  • Loading branch information
chrisholmes and fbogsany authored Aug 10, 2022
1 parent d3990c6 commit 844476b
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def initialize(endpoint: ENV.fetch('OTEL_EXPORTER_JAEGER_ENDPOINT', 'http://loca
username: ENV['OTEL_EXPORTER_JAEGER_USER'],
password: ENV['OTEL_EXPORTER_JAEGER_PASSWORD'],
timeout: ENV.fetch('OTEL_EXPORTER_JAEGER_TIMEOUT', 10),
ssl_verify_mode: CollectorExporter.ssl_verify_mode)
ssl_verify_mode: CollectorExporter.ssl_verify_mode,
metrics_reporter: nil)
raise ArgumentError, "invalid url for Jaeger::CollectorExporter #{endpoint}" unless OpenTelemetry::Common::Utilities.valid_url?(endpoint)
raise ArgumentError, 'username and password should either both be nil or both be set' if username.nil? != password.nil?

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

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

OpenTelemetry::Common::Utilities.untraced do
@transport.flush
measure_request_duration do
@transport.flush
end
end
SUCCESS
rescue StandardError => e
@metrics_reporter.add_to_counter('otel.jaeger_exporter.failure', labels: { 'reason' => e.class.to_s })
OpenTelemetry.handle_error(exception: e, message: 'unexpected error in Jaeger::CollectorExporter#export')
FAILURE
end
Expand Down Expand Up @@ -95,6 +100,15 @@ def encoded_batches(span_data)
Thrift::Batch.new('process' => process, 'spans' => spans)
end
end

def measure_request_duration
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
yield
ensure
stop = Process.clock_gettime(Process::CLOCK_MONOTONIC)
duration_ms = 1000.0 * (stop - start)
@metrics_reporter.record_value('otel.jaeger_exporter.request_duration', value: duration_ms)
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions exporter/jaeger/opentelemetry-exporter-jaeger.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'minitest', '~> 5.0'
spec.add_development_dependency 'opentelemetry-test-helpers'
spec.add_development_dependency 'rake', '~> 12.0'
spec.add_development_dependency 'rspec-mocks'
spec.add_development_dependency 'rubocop', '~> 0.73.0'
spec.add_development_dependency 'simplecov', '~> 0.17'
spec.add_development_dependency 'webmock', '~> 3.7.6'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
DEFAULT_JAEGER_COLLECTOR_ENDPOINT = 'http://localhost:14268/api/traces'

describe OpenTelemetry::Exporter::Jaeger::CollectorExporter do
let(:metrics_reporter) { double }
before(:each) do
allow(metrics_reporter).to receive(:record_value)
end

describe '#initialize' do
it 'initializes with defaults' do
exp = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new
Expand Down Expand Up @@ -175,5 +180,46 @@
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::SUCCESS)
assert_requested(stub_post)
end

describe '#metrics_reporter' do
it 'reports metrics for failures' do
expect(metrics_reporter).to receive(:add_to_counter).with('otel.jaeger_exporter.failure', labels: { 'reason' => 'Thrift::TransportException' })

stub_post = stub_request(:post, DEFAULT_JAEGER_COLLECTOR_ENDPOINT).to_return(status: 500)
exporter = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(
metrics_reporter: metrics_reporter
)
span_data = create_span_data
result = exporter.export([span_data])
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::FAILURE)
assert_requested(stub_post)
end

it 'reports metrics for timeouts' do
expect(metrics_reporter).to receive(:add_to_counter).with('otel.jaeger_exporter.failure', labels: { 'reason' => 'Net::OpenTimeout' })

stub_post = stub_request(:post, DEFAULT_JAEGER_COLLECTOR_ENDPOINT).to_timeout
exporter = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(
metrics_reporter: metrics_reporter
)
span_data = create_span_data
result = exporter.export([span_data])
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::FAILURE)
assert_requested(stub_post)
end

it 'records request duration' do
expect(metrics_reporter).to receive(:record_value).with('otel.jaeger_exporter.request_duration', hash_including(value: kind_of(Float)))
stub_post = stub_request(:post, DEFAULT_JAEGER_COLLECTOR_ENDPOINT).to_return(status: 200)

exporter = OpenTelemetry::Exporter::Jaeger::CollectorExporter.new(
metrics_reporter: metrics_reporter
)
span_data = create_span_data
result = exporter.export([span_data])
_(result).must_equal(OpenTelemetry::SDK::Trace::Export::SUCCESS)
assert_requested(stub_post)
end
end
end
end
1 change: 1 addition & 0 deletions exporter/jaeger/test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
require 'opentelemetry/exporter/jaeger'
require 'minitest/autorun'
require 'webmock/minitest'
require 'rspec/mocks/minitest_integration'

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

0 comments on commit 844476b

Please sign in to comment.