[opentelemetry_tesla] Conditionally override propagator (#176)
* Optionally disable trace propagation for Tesla While we always want spans being produced, trace progation is not desirable in all cases - namely, when calling external parties, as that may leak sensitive information, like one present on Baggage. This patch introduces a new option `:propagate`, that defaults to `true`. Some tweaks are made to existing propagation test, fixing how options are used. The approach here is closer to what we see in some middleware tests of Tesla itself. * change to propagator override * change propagator to it uses global default * mix format * improve docs --------- Co-authored-by: Andrew Rosa <dev@andrewhr.io>
This commit is contained in:
parent
6a5fc4c884
commit
901b571b07
|
@ -12,6 +12,9 @@ defmodule Tesla.Middleware.OpenTelemetry do
|
|||
|
||||
- `:span_name` - override span name. Can be a `String` for a static span name,
|
||||
or a function that takes the `Tesla.Env` and returns a `String`
|
||||
- `:propagator` - configures trace headers propagators. Setting it to `:none` disables propagation.
|
||||
Any module that implements `:otel_propagator_text_map` can be used.
|
||||
Defaults to calling `:otel_propagator_text_map.get_text_map_injector/0`
|
||||
- `:mark_status_ok` - configures spans with a list of expected HTTP error codes to be marked as `ok`,
|
||||
not as an error-containing spans
|
||||
"""
|
||||
|
@ -29,7 +32,7 @@ defmodule Tesla.Middleware.OpenTelemetry do
|
|||
OpenTelemetry.Tracer.with_span span_name, %{kind: :client} do
|
||||
env
|
||||
|> maybe_put_additional_ok_statuses(opts[:mark_status_ok])
|
||||
|> Tesla.put_headers(:otel_propagator_text_map.inject([]))
|
||||
|> maybe_propagate(Keyword.get(opts, :propagator, :opentelemetry.get_text_map_injector()))
|
||||
|> Tesla.run(next)
|
||||
|> set_span_attributes()
|
||||
|> handle_result()
|
||||
|
@ -51,6 +54,16 @@ defmodule Tesla.Middleware.OpenTelemetry do
|
|||
end
|
||||
end
|
||||
|
||||
defp maybe_propagate(env, :none), do: env
|
||||
|
||||
defp maybe_propagate(env, propagator) do
|
||||
:otel_propagator_text_map.inject(
|
||||
propagator,
|
||||
env,
|
||||
fn key, value, env -> Tesla.put_header(env, key, value) end
|
||||
)
|
||||
end
|
||||
|
||||
defp maybe_put_additional_ok_statuses(env, [_ | _] = additional_ok_statuses) do
|
||||
case env.opts[:additional_ok_statuses] do
|
||||
nil -> Tesla.put_opt(env, :additional_ok_statuses, additional_ok_statuses)
|
||||
|
|
|
@ -491,27 +491,32 @@ defmodule Tesla.Middleware.OpenTelemetryTest do
|
|||
assert response_size == byte_size(response)
|
||||
end
|
||||
|
||||
test "Injects distributed tracing headers" do
|
||||
OpentelemetryTelemetry.start_telemetry_span(
|
||||
"tracer_id",
|
||||
"my_label",
|
||||
%{},
|
||||
%{kind: :client}
|
||||
)
|
||||
describe "trace propagation" do
|
||||
test "injects distributed tracing headers by default" do
|
||||
{:ok, env} = Tesla.get(client(), "/propagate-traces")
|
||||
|
||||
assert {:ok,
|
||||
%Tesla.Env{
|
||||
headers: [
|
||||
{"traceparent", traceparent}
|
||||
]
|
||||
}} =
|
||||
Tesla.Middleware.OpenTelemetry.call(
|
||||
_env = %Tesla.Env{url: ""},
|
||||
_next = [],
|
||||
_opts = []
|
||||
)
|
||||
assert traceparent = Tesla.get_header(env, "traceparent")
|
||||
assert is_binary(traceparent)
|
||||
|
||||
assert is_binary(traceparent)
|
||||
assert_receive {:span, span(name: _name, attributes: attributes)}
|
||||
assert %{"http.target": "/propagate-traces"} = :otel_attributes.map(attributes)
|
||||
end
|
||||
|
||||
test "optionally disable propagation but keep span report" do
|
||||
{:ok, env} = Tesla.get(client(propagator: :none), "/propagate-traces")
|
||||
|
||||
refute Tesla.get_header(env, "traceparent")
|
||||
|
||||
assert_receive {:span, span(name: _name, attributes: attributes)}
|
||||
assert %{"http.target": "/propagate-traces"} = :otel_attributes.map(attributes)
|
||||
end
|
||||
end
|
||||
|
||||
defp client(opts \\ []) do
|
||||
[
|
||||
{Tesla.Middleware.OpenTelemetry, opts}
|
||||
]
|
||||
|> Tesla.client(fn env -> {:ok, env} end)
|
||||
end
|
||||
|
||||
defp endpoint_url(port), do: "http://localhost:#{port}/"
|
||||
|
|
Loading…
Reference in New Issue