Skip to content

Commit

Permalink
tests are green
Browse files Browse the repository at this point in the history
  • Loading branch information
deadtrickster committed Sep 4, 2017
1 parent a0cf61a commit e46d627
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 40 deletions.
12 changes: 12 additions & 0 deletions lib/prometheus/error.ex
Expand Up @@ -140,6 +140,18 @@ defmodule Prometheus.MissingMetricSpecKeyError do
end
end

defmodule Prometheus.InvalidBlockArityError do
@moduledoc """
Raised when fn passed as block has more then 0 arguments
"""
defexception [:args]

def message(%{args: args}) do
insp = Enum.map_join(args, ", ", &inspect/1)
"Fn with arity #{length(args)} (args: #{insp}) passed as block."
end
end

defmodule Prometheus.Error do
@moduledoc false

Expand Down
21 changes: 16 additions & 5 deletions lib/prometheus/injector.ex
Expand Up @@ -14,7 +14,18 @@ defmodule Prometheus.Injector do

# lambda
def inject_({:fn, fn_meta, [{:->, arrow_meta, [args, do_block]}]}, callback) do
{:fn, fn_meta, [{:->, arrow_meta, [args, callback.(do_block)]}]}
case args do
[] ->
callback.({{:., [],
[{:fn, fn_meta,
[{:->, arrow_meta,
[[], do_block]}]}]}, [],
[]})
_ ->
names = args
|> Enum.map(fn({name, _, _}) -> name end)
raise Prometheus.InvalidBlockArityError, args: names
end
end

# do_blocks can be simple calls or defs
Expand All @@ -23,7 +34,7 @@ defmodule Prometheus.Injector do
if have_defs(do_blocks) do
Enum.map(do_blocks, &inject_to_def(&1, callback))
else
[{:do, callback.({:__block__, [], do_blocks})}]
callback.({:__block__, [], do_blocks})
end
end

Expand All @@ -44,7 +55,7 @@ defmodule Prometheus.Injector do
end
end

# single dos, or other non-block stuff like function calls
# single do, or other non-block stuff like function calls
def inject_(thing, callback) do
inject_([{:do, {:__block__, [], [thing]}}], callback)
end
Expand Down Expand Up @@ -74,10 +85,10 @@ defmodule Prometheus.Injector do
defp inject_to_def({:def, def_meta, [head, [do: body]]}, callback) do
{:def, def_meta, [head, [do: callback.(body)]]}
end
defp inject_to_def({:def, def_meta, [head, [{:do, _do_block} | rest] = all]}, callback) do
defp inject_to_def({:def, def_meta, [head, [{:do, _do_block} | _rest] = all]}, callback) do
{:def, def_meta, [head, [do: callback.(
quote do
try unquote(all)
end)]]}
end)]]}
end
end
1 change: 1 addition & 0 deletions lib/prometheus/metric/counter.ex
Expand Up @@ -160,6 +160,7 @@ defmodule Prometheus.Metric.Counter do
env = __CALLER__
Prometheus.Injector.inject(fn(block) ->
quote do
require Prometheus.Error
try do
unquote(block)
else
Expand Down
40 changes: 27 additions & 13 deletions lib/prometheus/metric/gauge.ex
Expand Up @@ -158,33 +158,48 @@ defmodule Prometheus.Metric.Gauge do
end

@doc """
Sets the gauge identified by `spec` to the number of currently executing `fun`s.
Sets the gauge identified by `spec` to the number of currently executing `body`s.
Raises `Prometheus.UnknownMetricError` exception if a gauge
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
Raises `Prometheus.InvalidValueError` exception if fun isn't a function or block.
"""
defmacro track_inprogress(spec, fun) do
Erlang.metric_call(spec, [Erlang.ensure_fn(fun)])
end

defmacro track_inprogress(spec) do
quote do
@instrument {unquote(__MODULE__), :track_inprogress, unquote(spec)}
end
defmacro track_inprogress(spec, body) do
env = __CALLER__
Prometheus.Injector.inject(fn(block) ->
quote do
Prometheus.Metric.Gauge.inc(unquote(spec))
try do
unquote(block)
after
Prometheus.Metric.Gauge.dec(unquote(spec))
end
end
end, env, body)
end

@doc """
Tracks the amount of time spent executing `fun`.
Tracks the amount of time spent executing `body`.
Raises `Prometheus.UnknownMetricError` exception if a gauge
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
Raises `Prometheus.InvalidValueError` exception if `fun` isn't a function or block.
"""
defmacro set_duration(spec, fun) do
Erlang.metric_call(spec, [Erlang.ensure_fn(fun)])
defmacro set_duration(spec, body) do
env = __CALLER__
Prometheus.Injector.inject(fn(block) ->
quote do
start_time = :erlang.monotonic_time()
try do
unquote(block)
after
end_time = :erlang.monotonic_time()
Prometheus.Metric.Gauge.set(unquote(spec), end_time - start_time)
end
end
end, env, body)
end

@doc """
Expand Down Expand Up @@ -223,4 +238,3 @@ defmodule Prometheus.Metric.Gauge do
Erlang.metric_call(spec)
end
end

15 changes: 13 additions & 2 deletions lib/prometheus/metric/histogram.ex
Expand Up @@ -129,8 +129,19 @@ defmodule Prometheus.Metric.Histogram do
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
Raises `Prometheus.InvalidValueError` exception if fun isn't a function or block.
"""
defmacro observe_duration(spec, fun) do
Erlang.metric_call(spec, [Erlang.ensure_fn(fun)])
defmacro observe_duration(spec, body) do
env = __CALLER__
Prometheus.Injector.inject(fn(block) ->
quote do
start_time = :erlang.monotonic_time()
try do
unquote(block)
after
end_time = :erlang.monotonic_time()
Prometheus.Metric.Histogram.observe(unquote(spec), end_time - start_time)
end
end
end, env, body)
end

@doc """
Expand Down
15 changes: 13 additions & 2 deletions lib/prometheus/metric/summary.ex
Expand Up @@ -108,8 +108,19 @@ defmodule Prometheus.Metric.Summary do
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
Raises `Prometheus.InvalidValueError` exception if `fun` isn't a function or block.
"""
defmacro observe_duration(spec, fun) do
Erlang.metric_call(spec, [Erlang.ensure_fn(fun)])
defmacro observe_duration(spec, body) do
env = __CALLER__
Prometheus.Injector.inject(fn(block) ->
quote do
start_time = :erlang.monotonic_time()
try do
unquote(block)
after
end_time = :erlang.monotonic_time()
Prometheus.Metric.Summary.observe(unquote(spec), end_time - start_time)
end
end
end, env, body)
end

@doc """
Expand Down
5 changes: 3 additions & 2 deletions test/metric/injector_test.exs → test/injector_test.exs
Expand Up @@ -29,7 +29,6 @@ defmodule Prometheus.InjectorTest do
IO.puts("fun2")
end


Injector.test do
def fun3() do
IO.puts("fun3")
Expand All @@ -51,7 +50,9 @@ defmodule Prometheus.InjectorTest do
end

test "fn" do
assert capture_io(Injector.test(fn () -> IO.puts("qwe") end)) ==
assert capture_io(fn ->
Injector.test(fn () -> IO.puts("qwe") end)
end) ==
"before block\nqwe\nafter block\n"
end

Expand Down
16 changes: 10 additions & 6 deletions test/metric/gauge_test.exs
Expand Up @@ -88,17 +88,21 @@ defmodule Prometheus.GaugeTest do
end

## track_inprogress
assert_raise Prometheus.InvalidValueError,
"Invalid value: \"qwe\" (track_inprogress accepts only functions).",
assert_raise Prometheus.InvalidBlockArityError,
"Fn with arity 2 (args: :x, :y) passed as block.",
fn ->
Gauge.track_inprogress(spec, "qwe")
Macro.expand(quote do
Gauge.track_inprogress(spec, fn(x, y) -> 1 + x + y end)
end, __ENV__)
end

## set_duration
assert_raise Prometheus.InvalidValueError,
"Invalid value: \"qwe\" (set_duration accepts only functions).",
assert_raise Prometheus.InvalidBlockArityError,
"Fn with arity 2 (args: :x, :y) passed as block.",
fn ->
Gauge.set_duration(spec, "qwe")
Macro.expand(quote do
Gauge.set_duration(spec, fn(x, y) -> 1 + x + y end)
end, __ENV__)
end
end

Expand Down
16 changes: 9 additions & 7 deletions test/metric/histogram_test.exs
Expand Up @@ -91,13 +91,6 @@ defmodule Prometheus.HistogramTest do
fn ->
Histogram.dobserve(spec, "qwe")
end

## observe_duration
assert_raise Prometheus.InvalidValueError,
"Invalid value: \"qwe\" (observe_duration accepts only functions).",
fn ->
Histogram.observe_duration(spec, "qwe")
end
end

test "mf/arity errors" do
Expand Down Expand Up @@ -178,6 +171,15 @@ defmodule Prometheus.HistogramTest do
fn ->
Histogram.value([name: :metric_with_label, labels: [:l1, :l2]])
end

## observe_duration
assert_raise Prometheus.InvalidBlockArityError,
"Fn with arity 2 (args: :x, :y) passed as block.",
fn ->
Macro.expand(quote do
Histogram.observe_duration(spec, fn(x, y) -> 1 + x + y end)
end, __ENV__)
end
end

test "observe" do
Expand Down
8 changes: 5 additions & 3 deletions test/metric/summary_test.exs
Expand Up @@ -67,10 +67,12 @@ defmodule Prometheus.SummaryTest do
end

## observe_duration
assert_raise Prometheus.InvalidValueError,
"Invalid value: \"qwe\" (observe_duration accepts only functions).",
assert_raise Prometheus.InvalidBlockArityError,
"Fn with arity 2 (args: :x, :y) passed as block.",
fn ->
Summary.observe_duration(spec, "qwe")
Macro.expand(quote do
Summary.observe_duration(spec, fn(x, y) -> 1 + x + y end)
end, __ENV__)
end
end

Expand Down

0 comments on commit e46d627

Please sign in to comment.