Skip to content

Commit

Permalink
Merge branch 'master' of github.com:zachdaniel/spandex
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Jul 7, 2017
2 parents 6263cd3 + b2b57de commit 60e5901
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 74 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ elixir:
otp_release:
- 19.0
script:
- mix compile --warnings-as-errors
- mix credo --strict
- mix coveralls.travis
after_script:
- mix deps.get --only docs
- MIX_ENV=docs mix inch.report
- MIX_ENV=docs mix inch.report
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ There are 3 plugs provided for usage w/ Phoenix:

Ensure that `Spandex.Plug.EndTrace` goes *after* your router. This is important because we want rendering the response to be included in the tracing/timing. Put `Spandex.Plug.StartTrace` as early as is reasonable in your pipeline. Put `Spandex.Plug.AddContext` either after router or inside a pipeline in router.


## Logger metadata
In general, you'll probably want the current span_id and trace_id in your logs, so that you can find them in your tracing service. Make sure to add `span_id` and `trace_id` to logger_metadata

```
config :logger, :console,
metadata: [:request_id, :trace_id, :span_id]
```

## General Usage

In general, the nicest interface is to use function decorators.
Expand Down
2 changes: 1 addition & 1 deletion lib/plug/end_trace.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ defmodule Spandex.Plug.EndTrace do

defp error_count(%{status: status}) when status in 200..399,
do: 0
defp error_count(%{status: status}),
defp error_count(%{status: _status}),
do: 1
end
24 changes: 22 additions & 2 deletions lib/spandex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ defmodule Spandex do
defp truthy?(value) when value in [false, nil], do: false
defp truthy?(_other), do: true

delegate_to_adapter(:start_trace, [name])
def start_trace(name, attributes) do
case start_trace(name) do
{:ok, trace_id} ->
Logger.metadata([trace_id: trace_id])

Spandex.update_span(attributes)
{:error, error} -> {:error, error}
end
end

delegate_to_adapter(:start_span, [name])
def start_span(name, attributes) do
case start_span(name) do
{:ok, span_id} ->
Logger.metadata([span_id: span_id])

Spandex.update_span(attributes)
{:error, error} -> {:error, error}
end
end

delegate_to_adapter(:update_span, [context])
delegate_to_adapter(:update_top_span, [context])
delegate_to_adapter(:finish_trace, [])
Expand All @@ -63,6 +85,4 @@ defmodule Spandex do
delegate_to_adapter(:continue_trace, [name, trace_id, span_id])
delegate_to_adapter(:current_trace_id, [])
delegate_to_adapter(:current_span_id, [])
delegate_to_adapter(:start_trace, [name])
delegate_to_adapter(:start_span, [name])
end
67 changes: 21 additions & 46 deletions lib/trace_decorator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,30 @@ defmodule Spandex.TraceDecorator do
end
end
"""
use Decorator.Define, [span: 0, span: 1, trace: 0]
use Decorator.Define, [span: 0, span: 1, trace: 0, trace: 1]

def trace(body, context) do
trace([], body, context)
end

def trace(attributes, body, context) do
quote do
if Spandex.disabled?() do
unquote(body)
else
name = "#{unquote(context.name)}/#{unquote(context.arity)}"
_ =
case Spandex.start_trace(name) do
{:ok, trace_id} ->
Logger.metadata([trace_id: trace_id])
{:error, error} ->
{:error, error}
end
attributes = Enum.into(unquote(attributes), %{})

name = Spandex.TraceDecorator.span_name(attributes, unquote(context.name), unquote(context.arity))

_ = Spandex.start_trace(name, attributes)
try do
unquote(body)
rescue
exception ->
stacktrace = System.stacktrace
_ = Spandex.span_error(exception)
_ = Spandex.span_error(exception)

reraise(exception, stacktrace)
reraise(exception, stacktrace)
after
_ = Spandex.finish_trace
end
Expand All @@ -46,48 +47,18 @@ defmodule Spandex.TraceDecorator do
end

def span(body, context) do
quote do
if Spandex.disabled?() do
unquote(body)
else
name = "#{unquote(context.name)}/#{unquote(context.arity)}"
_ =
case Spandex.start_span(name) do
{:ok, span_id} ->
Logger.metadata([span_id: span_id])
{:error, error} ->
{:error, error}
end

try do
unquote(body)
rescue
exception ->
stacktrace = System.stacktrace()
_ = Spandex.span_error(exception)

reraise(exception, stacktrace)
after
_ = Spandex.finish_span()
end
end
end
span([], body, context)
end

def span(attributes, body, context) do
quote do
if Spandex.disabled?() do
unquote(body)
else
attributes = unquote(attributes)
name = attributes[:name] || "#{unquote(context.name)}/#{unquote(context.arity)}"
_ =
case Spandex.start_span(name) do
{:ok, span_id} ->
Logger.metadata([span_id: span_id])
{:error, error} ->
{:error, error}
end
attributes = Enum.into(unquote(attributes), %{})
name = Spandex.TraceDecorator.span_name(attributes, unquote(context.name), unquote(context.arity))

_ = Spandex.start_span(name, attributes)

try do
unquote(body)
Expand All @@ -103,4 +74,8 @@ defmodule Spandex.TraceDecorator do
end
end
end

def span_name(attributes, context_name, context_arity) do
attributes[:name] || "#{context_name}/#{context_arity}"
end
end
4 changes: 2 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Spandex.Mixfile do

def project do
[app: :spandex,
version: "1.0.1",
version: "1.0.2",
elixir: "~> 1.4",
elixirc_paths: elixirc_paths(Mix.env),
build_embedded: Mix.env == :prod,
Expand Down Expand Up @@ -67,7 +67,7 @@ defmodule Spandex.Mixfile do
[
{:confex, "3.2.0"},
{:credo, "~> 0.8", only: [:dev, :test], runtime: false},
{:decorator, "~> 1.2.0"},
{:decorator, "~> 1.2.2"},
{:ex_doc, ">= 0.0.0", only: :dev},
{:excoveralls, "~> 0.6", only: :test},
{:httpoison, "~> 0.11"},
Expand Down
44 changes: 22 additions & 22 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
"certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], []},
"confex": {:hex, :confex, "3.2.0", "4fdc818b14b1439b3e88b4f7bee50dea1eda4117871da236473e42bd4f36730d", [:mix], []},
"credo": {:hex, :credo, "0.8.1", "137efcc99b4bc507c958ba9b5dff70149e971250813cbe7d4537ec7e36997402", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]},
"decorator": {:hex, :decorator, "1.2.1", "46c9334f53c96b8b350f6556964ed79e08177cb1669f8a4ead2b32ecb39b2c8e", [:mix], []},
%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"},
"confex": {:hex, :confex, "3.2.0", "4fdc818b14b1439b3e88b4f7bee50dea1eda4117871da236473e42bd4f36730d", [:mix], [], "hexpm"},
"credo": {:hex, :credo, "0.8.1", "137efcc99b4bc507c958ba9b5dff70149e971250813cbe7d4537ec7e36997402", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"},
"decorator": {:hex, :decorator, "1.2.2", "28f88fe99b1ec462cb1a394e568f50fbd0e6e949602372a2d0365181c997ed7d", [:mix], [], "hexpm"},
"dialyxir": {:hex, :dialyxir, "0.5.0", "5bc543f9c28ecd51b99cc1a685a3c2a1a93216990347f259406a910cf048d1d7", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], []},
"ex_doc": {:hex, :ex_doc, "0.16.1", "b4b8a23602b4ce0e9a5a960a81260d1f7b29635b9652c67e95b0c2f7ccee5e81", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]},
"excoveralls": {:hex, :excoveralls, "0.7.0", "05cb3332c2b0f799df3ab90eb7df1ae5a147c86776e91792848a12b7ed87242f", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]},
"hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, optional: false]}, {:idna, "5.0.2", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
"httpoison": {:hex, :httpoison, "0.11.2", "9e59f17a473ef6948f63c51db07320477bad8ba88cf1df60a3eee01150306665", [:mix], [{:hackney, "~> 1.8.0", [hex: :hackney, optional: false]}]},
"idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, optional: false]}]},
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, optional: false]}]},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"msgpax": {:hex, :msgpax, "1.1.0", "e31625e256db2decca1ae2b841f21b4d2483b1332649ce3ebc96c7ff7a4986e3", [:mix], [{:plug, "~> 1.0", [hex: :plug, optional: true]}]},
"plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], []}}
"earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.16.1", "b4b8a23602b4ce0e9a5a960a81260d1f7b29635b9652c67e95b0c2f7ccee5e81", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.7.0", "05cb3332c2b0f799df3ab90eb7df1ae5a147c86776e91792848a12b7ed87242f", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"httpoison": {:hex, :httpoison, "0.11.2", "9e59f17a473ef6948f63c51db07320477bad8ba88cf1df60a3eee01150306665", [:mix], [{:hackney, "~> 1.8.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
"msgpax": {:hex, :msgpax, "1.1.0", "e31625e256db2decca1ae2b841f21b4d2483b1332649ce3ebc96c7ff7a4986e3", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm"},
"plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"}}
12 changes: 12 additions & 0 deletions test/datadog/adapter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ defmodule Spandex.Test.Datadog.AdapterTest do
end
end

test "a trace can specify additional attributes" do
TracedModule.trace_with_special_name()

assert(Util.find_span("special_name").service == :special_service)
end

test "a span can specify additional attributes" do
TracedModule.trace_with_special_name()

assert(Util.find_span("special_name_span").service == :special_span_service)
end

test "a complete trace sends a top level span" do
TracedModule.trace_one_thing()
span = Util.find_span("trace_one_thing/0")
Expand Down
10 changes: 10 additions & 0 deletions test/support/traced_module.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ defmodule Spandex.Test.TracedModule do
do_one_thing()
end

@decorate trace(%{name: "special_name", service: :special_service})
def trace_with_special_name() do
do_one_special_name_thing()
end

@decorate trace()
def trace_one_error() do
raise TestError, message: "trace_one_error"
Expand Down Expand Up @@ -58,4 +63,9 @@ defmodule Spandex.Test.TracedModule do
def do_one_thing() do
:timer.sleep(100)
end

@decorate span(name: "special_name_span", service: :special_span_service)
def do_one_special_name_thing() do
:timer.sleep(100)
end
end

0 comments on commit 60e5901

Please sign in to comment.