Skip to content

Commit

Permalink
allow overriding global configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
Jared Davis committed Apr 16, 2018
1 parent d949cfa commit 9573b5d
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 16 deletions.
29 changes: 27 additions & 2 deletions lib/ddtrace/contrib/grpc/datadog_interceptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ module GRPC
module DatadogInterceptor
# :nodoc:
class Base < ::GRPC::Interceptor
attr_accessor :datadog_pin

def initialize(options = {})
datadog_pin_configuration { |c| yield(c) if block_given? }
end

def request_response(**keywords)
trace(keywords) { yield }
end
Expand All @@ -23,12 +29,31 @@ def bidi_streamer(**keywords)

private

def pin
def datadog_pin_configuration
pin = default_datadog_pin

if block_given?
pin = Pin.new(
pin.service_name,
app: pin.app,
app_type: pin.app_type,
tracer: pin.tracer
)

yield(pin)
end

pin.onto(self)

pin
end

def default_datadog_pin
Pin.get_from(::GRPC)
end

def tracer
pin.tracer
datadog_pin.tracer
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def trace(keywords)

options = {
span_type: Datadog::Ext::GRPC::TYPE,
service: pin.service_name,
service: datadog_pin.service_name,
resource: format_resource(keywords[:method])
}

Expand Down
2 changes: 1 addition & 1 deletion lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Server < Base
def trace(keywords)
options = {
span_type: Datadog::Ext::GRPC::TYPE,
service: pin.service_name,
service: datadog_pin.service_name,
resource: format_resource(keywords[:method])
}
metadata = keywords[:call].metadata
Expand Down
16 changes: 15 additions & 1 deletion lib/ddtrace/contrib/grpc/interception_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class InterceptionContext
# our tracing middleware into the head of the call chain.
module InterceptWithDatadog
def intercept!(type, args = {})
unless defined?(@trace_started) && @trace_started
if should_prepend?
datadog_interceptor = choose_datadog_interceptor(args)

@interceptors.unshift(datadog_interceptor.new) if datadog_interceptor
Expand All @@ -21,6 +21,20 @@ def intercept!(type, args = {})

private

def should_prepend?
!trace_started? && !already_prepended?
end

def trace_started?
defined?(@trace_started) && @trace_started
end

def already_prepended?
@interceptors.any? do |interceptor|
interceptor.class.ancestors.include?(Datadog::Contrib::GRPC::DatadogInterceptor::Base)
end
end

def choose_datadog_interceptor(args)
if args.key?(:metadata)
Datadog::Contrib::GRPC::DatadogInterceptor::Client
Expand Down
31 changes: 30 additions & 1 deletion spec/ddtrace/contrib/grpc/datadog_interceptor/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
RSpec.describe 'tracing on the client connection' do
subject { Datadog::Contrib::GRPC::DatadogInterceptor::Client.new }

let(:span) { Datadog::Pin.get_from(::GRPC).tracer.writer.spans.first }
let(:span) { subject.datadog_pin.tracer.writer.spans.first }

before do
Datadog.configure do |c|
Expand All @@ -15,6 +15,35 @@
end
end

context 'using client-specific configurations' do
let(:keywords) do
{ request: instance_double(Object),
call: instance_double('GRPC::ActiveCall'),
method: 'MyService.Endpoint',
metadata: { some: 'datum' } }
end

let(:default_client_interceptor) do
Datadog::Contrib::GRPC::DatadogInterceptor::Client.new
end

let(:configured_client_interceptor) do
Datadog::Contrib::GRPC::DatadogInterceptor::Client.new do |c|
c.service_name = 'cepsr'
end
end

it 'replaces default service name' do
default_client_interceptor.request_response(keywords) {}
span = default_client_interceptor.datadog_pin.tracer.writer.spans.first
expect(span.service).to eq 'rspec'

configured_client_interceptor.request_response(keywords) {}
span = configured_client_interceptor.datadog_pin.tracer.writer.spans.first
expect(span.service).to eq 'cepsr'
end
end

shared_examples 'span data contents' do
specify { expect(span.name).to eq 'grpc.client' }
specify { expect(span.span_type).to eq 'grpc' }
Expand Down
25 changes: 25 additions & 0 deletions spec/ddtrace/contrib/grpc/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,31 @@
end
end

context 'multiple client configurations' do
let(:configured_interceptor) do
Datadog::Contrib::GRPC::DatadogInterceptor::Client.new do |c|
c.service_name = 'awesome sauce'
end
end
let(:alternate_client) do
GRPCHelper::TestService.rpc_stub_class.new(
'0.0.0.0:50051',
:this_channel_is_insecure,
interceptors: [configured_interceptor]
)
end

it 'uses the correct configuration information' do
run_request_reply
span = spans.first
expect(span.service).to eq 'rspec'

run_request_reply('0.0.0.0:50051', alternate_client)
span = configured_interceptor.datadog_pin.tracer.writer.spans.first
expect(span.service).to eq 'awesome sauce'
end
end

shared_examples 'associates child spans with the parent' do
let(:parent_span) { spans.first }
let(:child_span) { spans.last }
Expand Down
22 changes: 12 additions & 10 deletions spec/ddtrace/contrib/grpc/support/grpc_helper.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
require 'grpc'

module GRPCHelper
def run_request_reply
runner('0.0.0.0:50052') { |c| c.basic(TestMessage.new) }
def run_request_reply(address = '0.0.0.0:50052', client = nil)
runner(address, client) { |c| c.basic(TestMessage.new) }
end

def run_client_streamer
runner('0.0.0.0:50053') { |c| c.stream_from_client([TestMessage.new]) }
def run_client_streamer(address = '0.0.0.0:50053', client = nil)
runner(address, client) { |c| c.stream_from_client([TestMessage.new]) }
end

def run_server_streamer
runner('0.0.0.0:50054') { |c| c.stream_from_server(TestMessage.new) }
def run_server_streamer(address = '0.0.0.0:50054', client = nil)
runner(address, client) { |c| c.stream_from_server(TestMessage.new) }
end

def run_bidi_streamer
runner('0.0.0.0:50055') { |c| c.stream_both_ways([TestMessage.new]) }
def run_bidi_streamer(address = '0.0.0.0:50055', client = nil)
runner(address, client) { |c| c.stream_both_ways([TestMessage.new]) }
end

def runner(address)
def runner(address, client)
server = GRPC::RpcServer.new
server.add_http2_port(address, :this_port_is_insecure)
server.handle(TestService)

t = Thread.new { server.run }
server.wait_till_running

yield TestService.rpc_stub_class.new(address, :this_channel_is_insecure)
client ||= TestService.rpc_stub_class.new(address, :this_channel_is_insecure)

yield client

server.stop
until server.stopped?; end
Expand Down

0 comments on commit 9573b5d

Please sign in to comment.