From 7e0208c45fef4a51c55d5d327816ed513060a102 Mon Sep 17 00:00:00 2001 From: Robert Parcus <923630+rparcus@users.noreply.github.com> Date: Sat, 19 Oct 2024 04:53:45 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=90=9B=20Fix=20handler=20on=20streams?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/opentelemetry_finch.ex | 19 ++- .../test/opentelemetry_finch_test.exs | 110 ++++++++++++++++++ 2 files changed, 127 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex b/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex index ce9bbf67..849cd571 100644 --- a/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex +++ b/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex @@ -42,10 +42,25 @@ defmodule OpentelemetryFinch do end_time = :opentelemetry.timestamp() start_time = end_time - duration + # status = + # case meta.result do + # {:ok, response} -> response.status + # _ -> 0 + # end + status = case meta.result do - {:ok, response} -> response.status - _ -> 0 + {:ok, response} when is_map(response) -> + response.status + + {:ok, {_request, response}} when is_map(response) -> + response.status + + {:ok, {status, _headers, _body}} when is_integer(status) -> + status + + _ -> + 0 end url = build_url(meta.request.scheme, meta.request.host, meta.request.port, meta.request.path) diff --git a/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs b/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs index 98b44a65..31e6a46b 100644 --- a/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs +++ b/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs @@ -51,6 +51,110 @@ defmodule OpentelemetryFinchTest do } = :otel_attributes.map(attributes) end + test "records span on streamed requests where the acc is a 3 elements tuple", %{ + bypass: bypass, + test: finch_name + } do + Bypass.expect_once(bypass, "GET", "/", fn conn -> + Plug.Conn.send_resp(conn, 200, "OK") + end) + + OpentelemetryFinch.setup() + + _conn = start_supervised!({Finch, name: finch_name}) + + acc = {nil, [], ""} + + fun = fn + {:status, value}, {_, headers, body} -> {:cont, {value, headers, body}} + {:headers, value}, {status, headers, body} -> {:cont, {status, headers ++ value, body}} + {:data, value}, {status, headers, body} -> {:cont, {status, headers, body <> value}} + end + + assert {:ok, {200, [_ | _], "OK"}} = + Finch.build(:get, endpoint_url(bypass.port)) + |> Finch.stream_while(finch_name, acc, fun) + + assert_receive {:span, + span( + name: "HTTP GET", + kind: :client, + attributes: attributes + )} + + assert %{ + "net.peer.name": "localhost", + "http.method": "GET", + "http.target": "/", + "http.scheme": :http, + "http.status_code": 200 + } = :otel_attributes.map(attributes) + end + + test "records span on streamed requests where the acc is a 2 elements tuple", %{ + bypass: bypass, + test: finch_name + } do + Bypass.expect_once(bypass, "GET", "/", fn conn -> + Plug.Conn.send_resp(conn, 200, "OK") + end) + + OpentelemetryFinch.setup() + + _conn = start_supervised!({Finch, name: finch_name}) + + acc = {nil, %{body: "", headers: %{}, trailers: [], status: 200}} + + fun = fn + {:status, status}, {req, resp} -> + {:cont, {req, %{resp | status: status}}} + + {:headers, fields}, {req, resp} -> + fields = finch_fields_to_map(fields) + resp = update_in(resp.headers, &Map.merge(&1, fields)) + {:cont, {req, resp}} + + {:data, data}, acc -> + {:cont, acc} + + {:trailers, fields}, {req, resp} -> + fields = finch_fields_to_map(fields) + resp = update_in(resp.trailers, &Map.merge(&1, fields)) + {:cont, {req, resp}} + end + + assert {:ok, + {_request, + %{ + status: 200, + body: "", + headers: %{ + "cache-control" => _, + "content-length" => ["2"], + "date" => [_], + "server" => _ + }, + trailers: [] + }}} = + Finch.build(:get, endpoint_url(bypass.port)) + |> Finch.stream_while(finch_name, acc, fun) + + assert_receive {:span, + span( + name: "HTTP GET", + kind: :client, + attributes: attributes + )} + + assert %{ + "net.peer.name": "localhost", + "http.method": "GET", + "http.target": "/", + "http.scheme": :http, + "http.status_code": 200 + } = :otel_attributes.map(attributes) + end + test "records span on requests failed", %{bypass: _} do OpentelemetryFinch.setup() @@ -76,4 +180,10 @@ defmodule OpentelemetryFinchTest do end defp endpoint_url(port), do: "http://localhost:#{port}/" + + defp finch_fields_to_map(fields) do + Enum.reduce(fields, %{}, fn {name, value}, acc -> + Map.update(acc, name, [value], &(&1 ++ [value])) + end) + end end From 91808de09d14069ad17c2e4b2d611adc50325eb2 Mon Sep 17 00:00:00 2001 From: Robert Parcus <923630+rparcus@users.noreply.github.com> Date: Sat, 19 Oct 2024 05:02:34 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=8E=A8=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../opentelemetry_finch/lib/opentelemetry_finch.ex | 6 ------ 1 file changed, 6 deletions(-) diff --git a/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex b/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex index 849cd571..b9ad22c8 100644 --- a/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex +++ b/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex @@ -42,12 +42,6 @@ defmodule OpentelemetryFinch do end_time = :opentelemetry.timestamp() start_time = end_time - duration - # status = - # case meta.result do - # {:ok, response} -> response.status - # _ -> 0 - # end - status = case meta.result do {:ok, response} when is_map(response) -> From 9ac5b88376adf87808c7028cb3f3223abf9eab9b Mon Sep 17 00:00:00 2001 From: Robert Parcus <923630+rparcus@users.noreply.github.com> Date: Tue, 3 Dec 2024 13:20:44 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor=20meta=20hand?= =?UTF-8?q?ler=20to=20match=20on=20status=20presence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/opentelemetry_finch.ex | 15 ++++----------- .../test/opentelemetry_finch_test.exs | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex b/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex index b9ad22c8..d6251d0a 100644 --- a/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex +++ b/instrumentation/opentelemetry_finch/lib/opentelemetry_finch.ex @@ -44,17 +44,10 @@ defmodule OpentelemetryFinch do status = case meta.result do - {:ok, response} when is_map(response) -> - response.status - - {:ok, {_request, response}} when is_map(response) -> - response.status - - {:ok, {status, _headers, _body}} when is_integer(status) -> - status - - _ -> - 0 + {:ok, %{status: status}} when is_integer(status) -> status + {:ok, {_request, %{status: status}}} when is_integer(status) -> status + {:ok, {status, _headers, _body}} when is_integer(status) -> status + _ -> 0 end url = build_url(meta.request.scheme, meta.request.host, meta.request.port, meta.request.path) diff --git a/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs b/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs index 31e6a46b..d3f3a976 100644 --- a/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs +++ b/instrumentation/opentelemetry_finch/test/opentelemetry_finch_test.exs @@ -114,7 +114,7 @@ defmodule OpentelemetryFinchTest do resp = update_in(resp.headers, &Map.merge(&1, fields)) {:cont, {req, resp}} - {:data, data}, acc -> + {:data, _data}, acc -> {:cont, acc} {:trailers, fields}, {req, resp} ->