From e750fd6976dab83771399fde0e25859623246b73 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sat, 9 May 2020 10:45:55 -0600 Subject: [PATCH 1/8] use router dispatch start events to update name of span --- lib/opentelemetry_plug.ex | 32 ++++++++++++++++++++++---------- mix.exs | 2 +- mix.lock | 2 +- test/opentelemetry_plug_test.exs | 1 - 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/opentelemetry_plug.ex b/lib/opentelemetry_plug.ex index cf70547..c8c6b99 100644 --- a/lib/opentelemetry_plug.ex +++ b/lib/opentelemetry_plug.ex @@ -27,34 +27,40 @@ defmodule OpentelemetryPlug do # register the tracer. just re-registers if called for multiple repos _ = OpenTelemetry.register_application_tracer(:opentelemetry_plug) + :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_phoenix_tracer_router_start}}, + [:phoenix, :router_dispatch, :start], + &__MODULE__.handle_route/4, + config) + + :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_router_start}}, + [:plug, :router_dispatch, :start], + &__MODULE__.handle_route/4, + config) + :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_start}}, - event_prefix ++ [:start], + [:plug_adapter, :call, :start], &__MODULE__.handle_start/4, config) :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_stop}}, - event_prefix ++ [:stop], + [:plug_adapter, :call, :stop], &__MODULE__.handle_stop/4, config) :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_exception}}, - event_prefix ++ [:exception], + [:plug_adapter, :call, :exception], &__MODULE__.handle_exception/4, config) end @doc false def handle_start(_, _measurements, %{conn: conn}, _config) do + # TODO: add config for what paths are traced + # setup OpenTelemetry context based on request headers :ot_propagation.http_extract(conn.req_headers) - # TODO: add config option to allow `conn.request_path` as span name - span_name = case Map.get(conn.private, :plug_route) do - nil -> - "HTTP " <> conn.method - {route, _fun} -> - route - end + span_name = "HTTP " <> conn.method {_, adapter} = conn.adapter user_agent = header_or_empty(conn, "User-Agent") @@ -79,6 +85,12 @@ defmodule OpentelemetryPlug do OpenTelemetry.Tracer.start_span(span_name, %{attributes: attributes}) end + @doc false + def handle_route(_, _measurements, %{route: route}, _config) do + # TODO: add config option to allow `conn.request_path` as span name + OpenTelemetry.Span.update_name(route) + end + @doc false def handle_stop(_, _measurements, %{conn: conn}, _config) do OpenTelemetry.Span.set_attribute("http.status", conn.status) diff --git a/mix.exs b/mix.exs index 7b9d7eb..fdbe9f3 100644 --- a/mix.exs +++ b/mix.exs @@ -21,7 +21,7 @@ defmodule OpentelemetryPlug.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:plug, "~> 1.10"}, + {:plug, github: "elixir-plug/plug", branch: "master"}, {:opentelemetry_api, "~> 0.3"}, {:opentelemetry, "~> 0.3"}, {:telemetry, "~> 0.4"} diff --git a/mix.lock b/mix.lock index b9b1713..a70bee3 100644 --- a/mix.lock +++ b/mix.lock @@ -2,7 +2,7 @@ "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"}, "opentelemetry": {:hex, :opentelemetry, "0.4.0", "293729f014009b03a1a2c47e6367db6f280b41412faa5639f06dcce9733d18a6", [:rebar3], [{:opentelemetry_api, "~> 0.3.1", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "f0eb4281f26879147322b0a6f1c457c57f3f1c4121cbff1f6056e4c98b1647a7"}, "opentelemetry_api": {:hex, :opentelemetry_api, "0.3.1", "aa042f9ff0b774c3e9827e215fcf972d5cfccd9a79ed55194b58c329a945b486", [:mix, :rebar3], [], "hexpm", "91fc78c521b9fc7f72f47144bb9f0838d57584b1be5bbd3098d8aaf2f2d42686"}, - "plug": {:hex, :plug, "1.10.0", "6508295cbeb4c654860845fb95260737e4a8838d34d115ad76cd487584e2fc4d", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "422a9727e667be1bf5ab1de03be6fa0ad67b775b2d84ed908f3264415ef29d4a"}, + "plug": {:git, "https://github.com/elixir-plug/plug.git", "9c880dee5a3d55c81f97a87076e540a9b5878cbd", [branch: "master"]}, "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"}, "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"}, } diff --git a/test/opentelemetry_plug_test.exs b/test/opentelemetry_plug_test.exs index dfa65ae..ca514ea 100644 --- a/test/opentelemetry_plug_test.exs +++ b/test/opentelemetry_plug_test.exs @@ -39,7 +39,6 @@ defmodule MyRouter do use Plug.Router plug :match - plug Plug.Telemetry, event_prefix: [:my, :plug] plug :dispatch forward "/hello/:foo", to: MyPlug From d5bca1a4657c24cca95fa9b6d217a9058501119e Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sat, 16 May 2020 16:20:23 -0600 Subject: [PATCH 2/8] remove event_prefix from setup args --- lib/opentelemetry_plug.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/opentelemetry_plug.ex b/lib/opentelemetry_plug.ex index c8c6b99..fae3137 100644 --- a/lib/opentelemetry_plug.ex +++ b/lib/opentelemetry_plug.ex @@ -12,7 +12,7 @@ defmodule OpentelemetryPlug do Example: - OpentelemetryPlug.setup([:my, :plug]) + OpentelemetryPlug.setup([]) You may also supply the following options in the second argument: @@ -23,7 +23,7 @@ defmodule OpentelemetryPlug do defaults to the concatenation of the event name with periods, e.g. `"my.plug.start"`. """ - def setup(event_prefix, config \\ []) do + def setup(config \\ []) do # register the tracer. just re-registers if called for multiple repos _ = OpenTelemetry.register_application_tracer(:opentelemetry_plug) From 7ead271cf8b1535009ea193cf2c618c449939206 Mon Sep 17 00:00:00 2001 From: Garth Kidd Date: Sun, 24 May 2020 09:23:56 +1000 Subject: [PATCH 3/8] remove event_prefix from handler identifiers --- lib/opentelemetry_plug.ex | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/opentelemetry_plug.ex b/lib/opentelemetry_plug.ex index fae3137..3858b2a 100644 --- a/lib/opentelemetry_plug.ex +++ b/lib/opentelemetry_plug.ex @@ -27,27 +27,31 @@ defmodule OpentelemetryPlug do # register the tracer. just re-registers if called for multiple repos _ = OpenTelemetry.register_application_tracer(:opentelemetry_plug) - :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_phoenix_tracer_router_start}}, + :telemetry.attach({__MODULE__, :phoenix_tracer_router_start}, [:phoenix, :router_dispatch, :start], &__MODULE__.handle_route/4, config) - :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_router_start}}, + :telemetry.attach( + {__MODULE__, :plug_tracer_router_start}, [:plug, :router_dispatch, :start], &__MODULE__.handle_route/4, config) - :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_start}}, + :telemetry.attach( + {__MODULE__, :plug_tracer_start}, [:plug_adapter, :call, :start], &__MODULE__.handle_start/4, config) - :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_stop}}, + :telemetry.attach( + {__MODULE__, :plug_tracer_stop}, [:plug_adapter, :call, :stop], &__MODULE__.handle_stop/4, config) - :telemetry.attach({__MODULE__, {event_prefix, :opentelemetry_plug_tracer_exception}}, + :telemetry.attach( + {__MODULE__, :plug_tracer_exception}, [:plug_adapter, :call, :exception], &__MODULE__.handle_exception/4, config) From 70d95a89e46029d50c2c1d30653032eedc26fa67 Mon Sep 17 00:00:00 2001 From: Garth Kidd Date: Sun, 24 May 2020 09:47:16 +1000 Subject: [PATCH 4/8] upgrade to plug 1.10.1 for the router events --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index fdbe9f3..4381c67 100644 --- a/mix.exs +++ b/mix.exs @@ -21,7 +21,7 @@ defmodule OpentelemetryPlug.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:plug, github: "elixir-plug/plug", branch: "master"}, + {:plug, "~> 1.10.1"}, {:opentelemetry_api, "~> 0.3"}, {:opentelemetry, "~> 0.3"}, {:telemetry, "~> 0.4"} diff --git a/mix.lock b/mix.lock index a70bee3..afaa377 100644 --- a/mix.lock +++ b/mix.lock @@ -2,7 +2,7 @@ "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"}, "opentelemetry": {:hex, :opentelemetry, "0.4.0", "293729f014009b03a1a2c47e6367db6f280b41412faa5639f06dcce9733d18a6", [:rebar3], [{:opentelemetry_api, "~> 0.3.1", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "f0eb4281f26879147322b0a6f1c457c57f3f1c4121cbff1f6056e4c98b1647a7"}, "opentelemetry_api": {:hex, :opentelemetry_api, "0.3.1", "aa042f9ff0b774c3e9827e215fcf972d5cfccd9a79ed55194b58c329a945b486", [:mix, :rebar3], [], "hexpm", "91fc78c521b9fc7f72f47144bb9f0838d57584b1be5bbd3098d8aaf2f2d42686"}, - "plug": {:git, "https://github.com/elixir-plug/plug.git", "9c880dee5a3d55c81f97a87076e540a9b5878cbd", [branch: "master"]}, + "plug": {:hex, :plug, "1.10.1", "c56a6d9da7042d581159bcbaef873ba9d87f15dce85420b0d287bca19f40f9bd", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "b5cd52259817eb8a31f2454912ba1cff4990bca7811918878091cb2ab9e52cb8"}, "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"}, "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"}, } From 07bc298eeaa4ad150c0e4e46aefd46ab5a2a0770 Mon Sep 17 00:00:00 2001 From: Garth Kidd Date: Sun, 24 May 2020 14:17:11 +1000 Subject: [PATCH 5/8] mix format --- .formatter.exs | 1 + lib/opentelemetry_plug.ex | 69 +++++++++++++++++++------------- test/opentelemetry_plug_test.exs | 1 + 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index d2cda26..54bd0b6 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,5 @@ # Used by "mix format" [ + import_deps: [:plug], inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] ] diff --git a/lib/opentelemetry_plug.ex b/lib/opentelemetry_plug.ex index 3858b2a..a64b5f6 100644 --- a/lib/opentelemetry_plug.ex +++ b/lib/opentelemetry_plug.ex @@ -27,34 +27,40 @@ defmodule OpentelemetryPlug do # register the tracer. just re-registers if called for multiple repos _ = OpenTelemetry.register_application_tracer(:opentelemetry_plug) - :telemetry.attach({__MODULE__, :phoenix_tracer_router_start}, + :telemetry.attach( + {__MODULE__, :phoenix_tracer_router_start}, [:phoenix, :router_dispatch, :start], &__MODULE__.handle_route/4, - config) + config + ) :telemetry.attach( {__MODULE__, :plug_tracer_router_start}, [:plug, :router_dispatch, :start], &__MODULE__.handle_route/4, - config) + config + ) :telemetry.attach( {__MODULE__, :plug_tracer_start}, [:plug_adapter, :call, :start], &__MODULE__.handle_start/4, - config) + config + ) :telemetry.attach( {__MODULE__, :plug_tracer_stop}, [:plug_adapter, :call, :stop], &__MODULE__.handle_stop/4, - config) + config + ) :telemetry.attach( {__MODULE__, :plug_tracer_exception}, [:plug_adapter, :call, :exception], &__MODULE__.handle_exception/4, - config) + config + ) end @doc false @@ -71,19 +77,21 @@ defmodule OpentelemetryPlug do host = header_or_empty(conn, "Host") peer_ip = Map.get(Map.get(adapter, :peer_data), :address) - attributes = [{"http.target", conn.request_path}, - {"http.host", conn.host}, - {"http.scheme", conn.scheme}, - {"http.user_agent", user_agent}, - {"http.method", conn.method}, - {"net.peer.ip", to_string(:inet_parse.ntoa(peer_ip))}, - {"net.peer.port", adapter.peer_data.port}, - {"net.peer.name", host}, - {"net.transport", "IP.TCP"}, - {"net.host.ip", to_string(:inet_parse.ntoa(conn.remote_ip))}, - {"net.host.port", conn.port} | optional_attributes(conn) - # {"net.host.name", HostName} - ] + attributes = [ + {"http.target", conn.request_path}, + {"http.host", conn.host}, + {"http.scheme", conn.scheme}, + {"http.user_agent", user_agent}, + {"http.method", conn.method}, + {"net.peer.ip", to_string(:inet_parse.ntoa(peer_ip))}, + {"net.peer.port", adapter.peer_data.port}, + {"net.peer.name", host}, + {"net.transport", "IP.TCP"}, + {"net.host.ip", to_string(:inet_parse.ntoa(conn.remote_ip))}, + {"net.host.port", conn.port} | optional_attributes(conn) + # {"net.host.name", HostName} + ] + # TODO: Plug should provide a monotonic native time in measurements to use here # for the `start_time` option OpenTelemetry.Tracer.start_span(span_name, %{attributes: attributes}) @@ -111,6 +119,7 @@ defmodule OpentelemetryPlug do case Plug.Conn.get_req_header(conn, header) do [] -> "" + [host | _] -> host end @@ -119,21 +128,25 @@ defmodule OpentelemetryPlug do defp optional_attributes(conn) do # for some reason Elixir removed Enum.filter_map in 1.5 # so just using Erlang's list module - :lists.filtermap(fn({attr, fun}) -> - case fun.(conn) do - nil -> - false; - value -> - {true, {attr, value}} - end - end, [{"http.client_ip", &client_ip/1}, - {"http.server_name", &server_name/1}]) + :lists.filtermap( + fn {attr, fun} -> + case fun.(conn) do + nil -> + false + + value -> + {true, {attr, value}} + end + end, + [{"http.client_ip", &client_ip/1}, {"http.server_name", &server_name/1}] + ) end defp client_ip(conn) do case Plug.Conn.get_req_header(conn, "X-Forwarded-For") do [] -> nil + [host | _] -> host end diff --git a/test/opentelemetry_plug_test.exs b/test/opentelemetry_plug_test.exs index ca514ea..1ecf969 100644 --- a/test/opentelemetry_plug_test.exs +++ b/test/opentelemetry_plug_test.exs @@ -27,6 +27,7 @@ defmodule MyPlug do conn |> put_resp_content_type("text/plain") |> send_resp(400, "no span context") + _ -> conn |> put_resp_content_type("text/plain") From ecc06152c8b352a2919aed1e4e823a80f15af104 Mon Sep 17 00:00:00 2001 From: Garth Kidd Date: Mon, 25 May 2020 09:18:14 +1000 Subject: [PATCH 6/8] don't crash handler if :start skipped If one of our user's tests don't call through a `Plug.Conn.Adapter` that calls `:telemetry.execute/4` with a `[:plug_adapter, :call, :start]` event as expected, our handler will crash out loudly when their router calls `:telemetry.execute/4` with `[:plug, :router_dispatch, :start]` or `[:phoenix, :router_dispatch, :start]` if we don't take care to avoid calling `OpenTelemetry.Span.set_attribute/2` when the span context is `:undefined`. --- lib/opentelemetry_plug.ex | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/opentelemetry_plug.ex b/lib/opentelemetry_plug.ex index a64b5f6..026e30a 100644 --- a/lib/opentelemetry_plug.ex +++ b/lib/opentelemetry_plug.ex @@ -100,21 +100,29 @@ defmodule OpentelemetryPlug do @doc false def handle_route(_, _measurements, %{route: route}, _config) do # TODO: add config option to allow `conn.request_path` as span name - OpenTelemetry.Span.update_name(route) + if in_span?() do + OpenTelemetry.Span.update_name(route) + end end @doc false def handle_stop(_, _measurements, %{conn: conn}, _config) do - OpenTelemetry.Span.set_attribute("http.status", conn.status) - OpenTelemetry.Tracer.end_span() + if in_span?() do + OpenTelemetry.Span.set_attribute("http.status", conn.status) + OpenTelemetry.Tracer.end_span() + end end @doc false def handle_exception(_, _measurements, %{conn: _conn}, _config) do - OpenTelemetry.Span.set_status(OpenTelemetry.status('UnknownError', "unknown error")) - OpenTelemetry.Tracer.end_span() + if in_span?() do + OpenTelemetry.Span.set_status(OpenTelemetry.status('UnknownError', "unknown error")) + OpenTelemetry.Tracer.end_span() + end end + defp in_span?, do: OpenTelemetry.Tracer.current_ctx() != :undefined + defp header_or_empty(conn, header) do case Plug.Conn.get_req_header(conn, header) do [] -> From 2da4a0f420198b7dc4a5854759bb6ff963699c4f Mon Sep 17 00:00:00 2001 From: Garth Kidd Date: Mon, 25 May 2020 11:36:06 +1000 Subject: [PATCH 7/8] use safe means to get peer data closes #6 --- lib/opentelemetry_plug.ex | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/opentelemetry_plug.ex b/lib/opentelemetry_plug.ex index 026e30a..9c7671c 100644 --- a/lib/opentelemetry_plug.ex +++ b/lib/opentelemetry_plug.ex @@ -72,10 +72,11 @@ defmodule OpentelemetryPlug do span_name = "HTTP " <> conn.method - {_, adapter} = conn.adapter + peer_data = Plug.Conn.get_peer_data(conn) + user_agent = header_or_empty(conn, "User-Agent") host = header_or_empty(conn, "Host") - peer_ip = Map.get(Map.get(adapter, :peer_data), :address) + peer_ip = Map.get(peer_data, :address) attributes = [ {"http.target", conn.request_path}, @@ -84,7 +85,7 @@ defmodule OpentelemetryPlug do {"http.user_agent", user_agent}, {"http.method", conn.method}, {"net.peer.ip", to_string(:inet_parse.ntoa(peer_ip))}, - {"net.peer.port", adapter.peer_data.port}, + {"net.peer.port", peer_data.port}, {"net.peer.name", host}, {"net.transport", "IP.TCP"}, {"net.host.ip", to_string(:inet_parse.ntoa(conn.remote_ip))}, From ab2aba15560a09b81af103b2af2c699b07cb8bb1 Mon Sep 17 00:00:00 2001 From: Garth Kidd Date: Sun, 24 May 2020 14:36:33 +1000 Subject: [PATCH 8/8] repair test Make requests through `Plug.Cowboy` to ensure the necessary `[:plug_adapter, :call, :start]` event, taking necessary dependencies on `hackney`, `plug`, and `plug_cowboy`. Smells more of an integration test, but gets the job done. --- mix.exs | 4 +++- mix.lock | 12 ++++++++++ test/opentelemetry_plug_test.exs | 39 +++++++++++++++++++++++++++----- test/test_helper.exs | 1 + 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/mix.exs b/mix.exs index 4381c67..71c99d3 100644 --- a/mix.exs +++ b/mix.exs @@ -21,9 +21,11 @@ defmodule OpentelemetryPlug.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:plug, "~> 1.10.1"}, + {:hackney, "~> 1.0", only: :test, runtime: false}, {:opentelemetry_api, "~> 0.3"}, {:opentelemetry, "~> 0.3"}, + {:plug, "~> 1.10.1"}, + {:plug_cowboy, "~> 2.2", only: :test, runtime: false}, {:telemetry, "~> 0.4"} ] end diff --git a/mix.lock b/mix.lock index afaa377..afdc654 100644 --- a/mix.lock +++ b/mix.lock @@ -1,8 +1,20 @@ %{ + "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"}, + "cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "04fd8c6a39edc6aaa9c26123009200fc61f92a3a94f3178c527b70b767c6e605"}, + "cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm", "79f954a7021b302186a950a32869dbc185523d99d3e44ce430cd1f3289f41ed4"}, + "hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e0100f8ef7d1124222c11ad362c857d3df7cb5f4204054f9f0f4a728666591fc"}, + "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "opentelemetry": {:hex, :opentelemetry, "0.4.0", "293729f014009b03a1a2c47e6367db6f280b41412faa5639f06dcce9733d18a6", [:rebar3], [{:opentelemetry_api, "~> 0.3.1", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "f0eb4281f26879147322b0a6f1c457c57f3f1c4121cbff1f6056e4c98b1647a7"}, "opentelemetry_api": {:hex, :opentelemetry_api, "0.3.1", "aa042f9ff0b774c3e9827e215fcf972d5cfccd9a79ed55194b58c329a945b486", [:mix, :rebar3], [], "hexpm", "91fc78c521b9fc7f72f47144bb9f0838d57584b1be5bbd3098d8aaf2f2d42686"}, + "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, "plug": {:hex, :plug, "1.10.1", "c56a6d9da7042d581159bcbaef873ba9d87f15dce85420b0d287bca19f40f9bd", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "b5cd52259817eb8a31f2454912ba1cff4990bca7811918878091cb2ab9e52cb8"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.2.1", "fcf58aa33227a4322a050e4783ee99c63c031a2e7f9a2eb7340d55505e17f30f", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3b43de24460d87c0971887286e7a20d40462e48eb7235954681a20cee25ddeb6"}, "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"}, + "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"}, "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"}, } diff --git a/test/opentelemetry_plug_test.exs b/test/opentelemetry_plug_test.exs index 1ecf969..1000233 100644 --- a/test/opentelemetry_plug_test.exs +++ b/test/opentelemetry_plug_test.exs @@ -1,15 +1,42 @@ defmodule OpentelemetryPlugTest do use ExUnit.Case - use Plug.Test + + setup_all do + OpentelemetryPlug.setup([]) + + {:ok, _} = Plug.Cowboy.http(MyPlug, [], ip: {127, 0, 0, 1}, port: 0) + + on_exit(fn -> + :ok = Plug.Cowboy.shutdown(MyPlug.HTTP) + end) + end test "creates span" do - conn = conn(:get, "/hello/world") + assert {200, _, "Hello world"} = request(:get, "/hello/world") + end - OpentelemetryPlug.setup([:my, :plug], []) - conn = MyRouter.call(conn, []) + defp base_url do + info = :ranch.info(MyPlug.HTTP) + port = Keyword.fetch!(info, :port) + ip = Keyword.fetch!(info, :ip) + "http://#{:inet.ntoa(ip)}:#{port}" + end + + defp request(:head = verb, path) do + {:ok, status, headers} = :hackney.request(verb, base_url() <> path, [], "", []) + {status, headers, nil} + end - assert conn.state == :sent - assert conn.status == 200 + defp request(verb, path, headers \\ [], body \\ "") do + case :hackney.request(verb, base_url() <> path, headers, body, []) do + {:ok, status, headers, client} -> + {:ok, body} = :hackney.body(client) + :hackney.close(client) + {status, headers, body} + + {:error, _} = error -> + error + end end end diff --git a/test/test_helper.exs b/test/test_helper.exs index 86c10a6..b254fd1 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,4 +1,5 @@ ExUnit.start() +Application.ensure_all_started(:hackney) Application.ensure_all_started(:opentelemetry_api) Application.ensure_all_started(:opentelemetry)