From 72679a66f6a854dceada515acdf4b8c7d50e4ee7 Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Thu, 26 Dec 2024 11:25:47 -0500 Subject: [PATCH] feat: add extra_attrs to tesla middleware --- .../opentelemetry_tesla_middleware.ex | 12 ++++--- .../opentelemetry_tesla_middleware_test.exs | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry_tesla/lib/middleware/opentelemetry_tesla_middleware.ex b/instrumentation/opentelemetry_tesla/lib/middleware/opentelemetry_tesla_middleware.ex index ab83ed7c..a71a5146 100644 --- a/instrumentation/opentelemetry_tesla/lib/middleware/opentelemetry_tesla_middleware.ex +++ b/instrumentation/opentelemetry_tesla/lib/middleware/opentelemetry_tesla_middleware.ex @@ -17,6 +17,7 @@ defmodule Tesla.Middleware.OpenTelemetry do 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 + - `:trace_attrs` - trace attributes to be added to the span. """ alias OpenTelemetry.SemanticConventions.Trace @@ -28,13 +29,14 @@ defmodule Tesla.Middleware.OpenTelemetry do def call(env, next, opts) do span_name = get_span_name(env, Keyword.get(opts, :span_name)) + trace_attrs = Keyword.get(opts, :trace_attrs, %{}) OpenTelemetry.Tracer.with_span span_name, %{kind: :client} do env |> maybe_put_additional_ok_statuses(opts[:mark_status_ok]) |> maybe_propagate(Keyword.get(opts, :propagator, :opentelemetry.get_text_map_injector())) |> Tesla.run(next) - |> set_span_attributes() + |> set_span_attributes(trace_attrs) |> handle_result() end end @@ -73,13 +75,15 @@ defmodule Tesla.Middleware.OpenTelemetry do defp maybe_put_additional_ok_statuses(env, _additional_ok_statuses), do: env - defp set_span_attributes({_, %Tesla.Env{} = env} = result) do - OpenTelemetry.Tracer.set_attributes(build_attrs(env)) + defp set_span_attributes({_, %Tesla.Env{} = env} = result, trace_attrs) do + trace_attrs + |> Map.merge(build_attrs(env)) + |> OpenTelemetry.Tracer.set_attributes() result end - defp set_span_attributes(result) do + defp set_span_attributes(result, _trace_attrs) do result end diff --git a/instrumentation/opentelemetry_tesla/test/middleware/opentelemetry_tesla_middleware_test.exs b/instrumentation/opentelemetry_tesla/test/middleware/opentelemetry_tesla_middleware_test.exs index 9fbee706..3a84bb57 100644 --- a/instrumentation/opentelemetry_tesla/test/middleware/opentelemetry_tesla_middleware_test.exs +++ b/instrumentation/opentelemetry_tesla/test/middleware/opentelemetry_tesla_middleware_test.exs @@ -125,6 +125,41 @@ defmodule Tesla.Middleware.OpenTelemetryTest do assert_receive {:span, span(name: "POST :my-high-cardinality-url", attributes: _attributes)} end + test "with extra attrs", + %{ + bypass: bypass + } do + defmodule TestClient do + def get(client) do + params = [id: ~c"3"] + + Tesla.get(client, "/users/:id", opts: [path_params: params]) + end + + def client(url) do + middleware = [ + {Tesla.Middleware.BaseUrl, url}, + {Tesla.Middleware.OpenTelemetry, extra_attrs: %{"peer.service" => "myservicename"}}, + Tesla.Middleware.PathParams + ] + + Tesla.client(middleware) + end + end + + Bypass.expect_once(bypass, "GET", "/users/3", fn conn -> + Plug.Conn.resp(conn, 204, "") + end) + + bypass.port + |> endpoint_url() + |> TestClient.client() + |> TestClient.get() + + assert_receive {:span, span(name: "HTTP GET", attributes: attributes)} + assert attributes["peer.service"] == "myservicename" + end + test "uses custom span name function when passed in middleware opts", %{ bypass: bypass