Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GRPCPropagator: handle metadata array values #1203

Merged
merged 8 commits into from
Oct 14, 2020
Merged
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
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 @@ -8,7 +8,7 @@ module Contrib
module GRPC
module DatadogInterceptor
# The DatadogInterceptor::Client implements the tracing strategy
# for gRPC client-side endpoitns. This middleware compoent will
# for gRPC client-side endpoints. This middleware component will
# inject trace context information into gRPC metadata prior to
# sending the request to the server.
class Client < Base
Expand Down
20 changes: 16 additions & 4 deletions lib/ddtrace/propagation/grpc_propagator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,36 @@ def valid?
end

def trace_id
value = @metadata[GRPC_METADATA_TRACE_ID].to_i
value = metadata_for_key(GRPC_METADATA_TRACE_ID).to_i
value if (1..Span::EXTERNAL_MAX_ID).cover? value
end

def parent_id
value = @metadata[GRPC_METADATA_PARENT_ID].to_i
value = metadata_for_key(GRPC_METADATA_PARENT_ID).to_i
value if (1..Span::EXTERNAL_MAX_ID).cover? value
end

def sampling_priority
value = @metadata[GRPC_METADATA_SAMPLING_PRIORITY]
value = metadata_for_key(GRPC_METADATA_SAMPLING_PRIORITY)
value && value.to_i
end

def origin
value = @metadata[GRPC_METADATA_ORIGIN]
value = metadata_for_key(GRPC_METADATA_ORIGIN)
value if value != ''
end

private

def metadata_for_key(key)
# metadata values can be arrays (multiple headers with the same key)
value = @metadata[key]
if value.is_a?(Array)
value.first
else
value
end
end
end
end
end
18 changes: 18 additions & 0 deletions spec/ddtrace/propagation/grpc_propagator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,23 @@
expect(subject.origin).to eq 'synthetics'
end
end

# Metadata values can also be arrays
# https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md
context 'given populated metadata in array format' do
let(:metadata) do
{ 'x-datadog-trace-id' => %w[12345 67890],
'x-datadog-parent-id' => %w[98765 43210],
'x-datadog-sampling-priority' => ['0'],
'x-datadog-origin' => ['synthetics'] }
end

it 'returns a populated context with the first metadata array values' do
expect(subject.trace_id).to eq 12345
expect(subject.span_id).to eq 98765
expect(subject.sampling_priority).to be_zero
expect(subject.origin).to eq 'synthetics'
end
end
end
end