Page MenuHomePhorge

No OneTemporary

Size
54 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/prometheus/buckets.ex b/lib/prometheus/buckets.ex
index b1973f5..01707ec 100644
--- a/lib/prometheus/buckets.ex
+++ b/lib/prometheus/buckets.ex
@@ -1,21 +1,19 @@
defmodule Prometheus.Buckets do
@moduledoc """
Histogram buckets generators.
"""
use Prometheus.Erlang, :prometheus_buckets
@doc """
iex(2)> Prometheus.Buckets.new(:default)
[0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, :infinity]
iex(3)> Prometheus.Buckets.new({:exponential, 100, 1.2, 3})
[100, 120, 144, :infinity]
iex(2)> Prometheus.Buckets.new({:linear, 10, 5, 6})
[10, 15, 20, 25, 30, 35, :infinity]
"""
- defmacro new(arg) do
- Erlang.call([arg])
- end
+ delegate new(arg)
end
diff --git a/lib/prometheus/collector.ex b/lib/prometheus/collector.ex
index b3d4bf8..d46bc6c 100644
--- a/lib/prometheus/collector.ex
+++ b/lib/prometheus/collector.ex
@@ -1,90 +1,88 @@
defmodule Prometheus.Collector do
@moduledoc """
A collector for a set of metrics.
Normal users should use `Prometheus.Metric.Gauge`, `Prometheus.Metric.Counter`,
`Prometheus.Metric.Summary`
and `Prometheus.Metric.Histogram`.
Implementing `:prometheus_collector` behaviour is for advanced uses such as proxying
metrics from another monitoring system.
It is the responsibility of the implementer to ensure produced metrics are valid.
You will be working with Prometheus data model directly (see `Prometheus.Model` ).
Callbacks:
- `collect_mf(registry, callback)` - called by exporters and formats.
Should call `callback` for each `MetricFamily` of this collector;
- `collect_metrics(name, data)` - called by `MetricFamily` constructor.
Should return Metric list for each MetricFamily identified by `name`.
`data` is a term associated with MetricFamily by collect_mf.
- `deregister_cleanup(registry)` - called when collector unregistered by
`registry`. If collector is stateful you can put cleanup code here.
Example (simplified [`:prometheus_vm_memory_collector`](https://github.com/deadtrickster/prometheus.erl/blob/master/doc/prometheus_vm_memory_collector.md)):
```
iex(3)> defmodule Prometheus.VMMemoryCollector do
...(3)> use Prometheus.Collector
...(3)>
...(3)> @labels [:processes, :atom, :binary, :code, :ets]
...(3)>
...(3)> def collect_mf(_registry, callback) do
...(3)> memory = :erlang.memory()
...(3)> callback.(create_gauge(
...(3)> :erlang_vm_bytes_total,
...(3)> "The total amount of memory currently allocated.",
...(3)> memory))
...(3)> :ok
...(3)> end
...(3)>
...(3)> def collect_metrics(:erlang_vm_bytes_total, memory) do
...(3)> Prometheus.Model.gauge_metrics(
...(3)> for label <- @labels do
...(3)> {[type: label], memory[label]}
...(3)> end)
...(3)> end
...(3)>
...(3)> defp create_gauge(name, help, data) do
...(3)> Prometheus.Model.create_mf(name, help, :gauge, __MODULE__, data)
...(3)> end
...(3)> end
iex(4)> Prometheus.Registry.register_collector(Prometheus.VMMemoryCollector)
:ok
iex(5)> r = ~r/# TYPE erlang_vm_bytes_total gauge
...(5)> # HELP erlang_vm_bytes_total
...(5)> The total amount of memory currently allocated.
...(5)> erlang_vm_bytes_total{type=\"processes\"} [1-9]
...(5)> erlang_vm_bytes_total{type=\"atom\"} [1-9]
...(5)> erlang_vm_bytes_total{type=\"binary\"} [1-9]
...(5)> erlang_vm_bytes_total{type=\"code\"} [1-9]
...(5)> erlang_vm_bytes_total{type=\"ets\"} [1-9]/
iex(6)> Regex.match?(r, Prometheus.Format.Text.format)
true
```
"""
defmacro __using__(_opts) do
quote location: :keep do
@behaviour :prometheus_collector
require Prometheus.Error
require Prometheus.Model
def deregister_cleanup(_registry) do
:ok
end
defoverridable deregister_cleanup: 1
end
end
use Prometheus.Erlang, :prometheus_collector
@doc """
Calls `callback` for each MetricFamily of this collector.
"""
- defmacro collect_mf(registry \\ :default, collector, callback) do
- Erlang.call([registry, collector, callback])
- end
+ delegate collect_mf(registry \\ :default, collector, callback)
end
diff --git a/lib/prometheus/contrib/mnesia.ex b/lib/prometheus/contrib/mnesia.ex
index 5bdcec2..83e9bdd 100644
--- a/lib/prometheus/contrib/mnesia.ex
+++ b/lib/prometheus/contrib/mnesia.ex
@@ -1,40 +1,31 @@
defmodule Prometheus.Contrib.Mnesia do
@moduledoc """
Mnesia instrumentation helpers.
"""
use Prometheus.Erlang, :prometheus_mnesia
@doc """
Returns sum of all mnesia files for the given `table` in bytes.
Mnesia can create different files for each table:
- .DAT - DETS files
- .TMP - temp files
- .DMP - dumped ets tables
- .DCD - disc copies data
- .DCL - disc copies log
- .LOGTMP - disc copies log
More on Mnesia files can be found in
<a href="http://erlang.org/doc/apps/mnesia/Mnesia_chap7.html">
Mnesia System Information chapter
</a> of Mnesia User's Guide
"""
- defmacro table_disk_size(
- dir \\ quote do
- :mnesia.system_info(:directory)
- end,
- table
- ) do
- Erlang.call([dir, table])
- end
+ delegate table_disk_size(dir \\ :mnesia.system_info(:directory), table)
@doc """
Returns {pcount, ccount} tuple, where
pcount is a number of participant transactions and
ccount is a number of coordinator transactions.
Can return {:undefined, :undefined} occasionally.
"""
- defmacro tm_info() do
- Erlang.call()
- end
+ delegate tm_info()
end
diff --git a/lib/prometheus/erlang.ex b/lib/prometheus/erlang.ex
index de1462c..285e41b 100644
--- a/lib/prometheus/erlang.ex
+++ b/lib/prometheus/erlang.ex
@@ -1,153 +1,50 @@
defmodule Prometheus.Erlang do
@moduledoc false
require Prometheus.Metric
alias Prometheus.Metric
defmacro __using__(erlang_module) do
quote do
@erlang_module unquote(erlang_module)
- alias Prometheus.Erlang
- end
- end
-
- defmacro call(mf \\ false, arguments \\ []) do
- {module, function, arguments} = parse_mfa(__CALLER__, mf, arguments)
-
- quote do
- Prometheus.Erlang.call_body(unquote(module), unquote(function), unquote(arguments))
- end
- end
- def call_body(module, function, arguments) do
- quote do
require Prometheus.Error
- Prometheus.Error.with_prometheus_error(
- unquote(module).unquote(function)(unquote_splicing(arguments))
- )
+ import unquote(__MODULE__)
end
end
- defmacro metric_call(mf_or_spec, spec \\ false, arguments \\ []) do
- {mf, spec, arguments} = parse_metric_call_args(mf_or_spec, spec, arguments)
-
- {module, function, arguments} = parse_mfa(__CALLER__, mf, arguments)
-
- quote do
- Prometheus.Erlang.metric_call_body(
- unquote(module),
- unquote(function),
- unquote(spec),
- unquote(arguments)
- )
- end
- end
-
- def metric_call_body(module, function, spec, arguments) do
- case spec do
- _ when Metric.ct_parsable_spec?(spec) ->
- {registry, name, labels} = Prometheus.Metric.parse_spec(spec)
-
- quote do
- require Prometheus.Error
+ defmacro delegate(fun, opts \\ []) do
+ fun = Macro.escape(fun, unquote: true)
- Prometheus.Error.with_prometheus_error(
- unquote(module).unquote(function)(
- unquote(registry),
- unquote(name),
- unquote(labels),
- unquote_splicing(arguments)
- )
- )
- end
+ quote bind_quoted: [fun: fun, opts: opts] do
+ target = Keyword.get(opts, :to, @erlang_module)
- _ ->
- quote do
- require Prometheus.Error
+ {name, args, as, as_args} = Kernel.Utils.defdelegate(fun, opts)
- {registry, name, labels} = Metric.parse_spec(unquote(spec))
-
- Prometheus.Error.with_prometheus_error(
- unquote(module).unquote(function)(
- registry,
- name,
- labels,
- unquote_splicing(arguments)
- )
- )
- end
- end
- end
-
- defp parse_metric_call_args(mf_or_spec, spec, arguments) do
- case mf_or_spec do
- ## Erlang.metric_call({:prometheus_counter, :dinc}, spec, [value])
- {_, _} ->
- {mf_or_spec, spec, arguments}
-
- ## Erlang.metric_call(:inc, spec, [value])
- _ when is_atom(mf_or_spec) ->
- {mf_or_spec, spec, arguments}
-
- _ ->
- ## args are 'shifted' to left
- [] = arguments
-
- if spec == false do
- ## only spec is needed, e.g. Erlang.metric_call(spec)
- {false, mf_or_spec, []}
- else
- ## Erlang.metric_call(spec, [value])
- {false, mf_or_spec, spec}
- end
+ def unquote(name)(unquote_splicing(args)) do
+ Prometheus.Error.with_prometheus_error(
+ unquote(target).unquote(as)(unquote_splicing(as_args))
+ )
+ end
end
end
- defp parse_mfa(caller, mf, arguments) do
- arguments =
- case mf do
- _ when is_list(mf) ->
- [] = arguments
- mf
-
- _ ->
- arguments
- end
+ defmacro delegate_metric(fun, opts \\ []) do
+ fun = Macro.escape(fun, unquote: true)
- {module, function} =
- case mf do
- false ->
- {f, _arity} = caller.function
- {Module.get_attribute(caller.module, :erlang_module), f}
+ quote bind_quoted: [fun: fun, opts: opts] do
+ target = Keyword.get(opts, :to, @erlang_module)
- _ when is_list(mf) ->
- {f, _arity} = caller.function
- {Module.get_attribute(caller.module, :erlang_module), f}
+ {name, args, as, [spec | as_args]} = Kernel.Utils.defdelegate(fun, opts)
- {_, _} ->
- mf
+ def unquote(name)(unquote_splicing(args)) do
+ {registry, name, labels} = Metric.parse_spec(unquote(spec))
- _ when is_atom(mf) ->
- {Module.get_attribute(caller.module, :erlang_module), mf}
+ Prometheus.Error.with_prometheus_error(
+ unquote(target).unquote(as)(registry, name, labels, unquote_splicing(as_args))
+ )
end
-
- {module, function, arguments}
- end
-
- def ensure_fn(var) do
- case var do
- [do: block] ->
- quote do
- fn ->
- unquote(block)
- end
- end
-
- fun ->
- quote do
- unquote(fun)
- end
end
end
end
diff --git a/lib/prometheus/metric.ex b/lib/prometheus/metric.ex
index f6a38dc..928599f 100644
--- a/lib/prometheus/metric.ex
+++ b/lib/prometheus/metric.ex
@@ -1,191 +1,185 @@
defmodule Prometheus.Metric do
@moduledoc """
Prometheus metrics shortcuts.
Aliases and requires respective metric modules so they are
accessible without `Prometheus.Metric` prefix.
Allows to automatically setup metrics with
`@<type>` attributes. Metrics will be declared in
the `@on_load` callback. If the module already
has `@on_load` callback, metrics will be declared
iff the callback returns `:ok`.
Example:
iex(1)> defmodule MyCoolModule do
...(1)> use Prometheus.Metric
...(1)>
...(1)> @counter name: :test_counter3, labels: [], help: "qwe"
...(1)> end
iex(2)> require Prometheus.Metric.Counter
Prometheus.Metric.Counter
iex(3)> Prometheus.Metric.Counter.value(:test_counter3)
0
"""
@metrics [:counter, :gauge, :boolean, :summary, :histogram]
defmacro __using__(_opts) do
module_name = __CALLER__.module
quote do
# credo:disable-for-next-line Credo.Check.Readability.SpaceAfterCommas
alias Prometheus.Metric.{Counter, Gauge, Histogram, Summary, Boolean}
# credo:disable-for-next-line Credo.Check.Readability.SpaceAfterCommas
require Prometheus.Metric.{Counter, Gauge, Histogram, Summary, Boolean}
require Prometheus.Error
unquote_splicing(
for metric <- @metrics do
quote do
Module.register_attribute(
unquote(module_name),
unquote(metric),
accumulate: true
)
end
end
)
@before_compile unquote(__MODULE__)
end
end
defmacro __before_compile__(env) do
mod = env.module
declarations =
for metric <- @metrics, params <- Module.delete_attribute(mod, metric) do
{metric, params}
end
quote do
def __declare_prometheus_metrics__() do
if List.keymember?(Application.started_applications(), :prometheus, 0) do
unquote_splicing(Enum.map(declarations, &emit_create_metric/1))
:ok
else
existing_metrics = Application.get_env(:prometheus, :default_metrics, [])
defined_metrics = unquote(Enum.map(declarations, &emit_metric_tuple/1))
Application.put_env(
:prometheus,
:default_metrics,
defined_metrics ++ existing_metrics
)
:ok
end
end
unquote(gen_on_load(env))
end
end
defp gen_on_load(env) do
case get_on_load_attribute(env.module) do
nil ->
quote do
@on_load :__declare_prometheus_metrics__
end
on_load ->
Module.delete_attribute(env.module, :on_load)
Module.put_attribute(env.module, :on_load, :__prometheus_on_load_override__)
quote do
def __prometheus_on_load_override__() do
case unquote(on_load)() do
:ok -> __declare_prometheus_metrics__()
result -> result
end
end
end
end
end
defp get_on_load_attribute(module) do
case Module.get_attribute(module, :on_load) do
[] ->
nil
nil ->
nil
atom when is_atom(atom) ->
atom
{atom, 0} when is_atom(atom) ->
atom
[{atom, 0}] when is_atom(atom) ->
atom
other ->
raise ArgumentError,
"expected the @on_load attribute to be an atom or a " <>
"{atom, 0} tuple, got: #{inspect(other)}"
end
end
defp emit_metric_tuple({metric, params}) do
quote do
{unquote(metric), unquote(params)}
end
end
defp emit_create_metric({metric, params}) do
emit_create_metric(metric, params)
end
defp emit_create_metric(:counter, params) do
quote do
Prometheus.Metric.Counter.declare(unquote(params))
end
end
defp emit_create_metric(:gauge, params) do
quote do
Prometheus.Metric.Gauge.declare(unquote(params))
end
end
defp emit_create_metric(:boolean, params) do
quote do
Prometheus.Metric.Boolean.declare(unquote(params))
end
end
defp emit_create_metric(:summary, params) do
quote do
Prometheus.Metric.Summary.declare(unquote(params))
end
end
defp emit_create_metric(:histogram, params) do
quote do
Prometheus.Metric.Histogram.declare(unquote(params))
end
end
- defmacro ct_parsable_spec?(spec) do
- quote do
- is_list(unquote(spec)) or is_atom(unquote(spec))
- end
- end
-
def parse_spec(spec) when is_list(spec) do
registry = Keyword.get(spec, :registry, :default)
name = Keyword.fetch!(spec, :name)
labels = Keyword.get(spec, :labels, [])
{registry, name, labels}
end
def parse_spec(spec) when is_atom(spec) do
{:default, spec, []}
end
end
diff --git a/lib/prometheus/metric/boolean.ex b/lib/prometheus/metric/boolean.ex
index b03a899..66a3719 100644
--- a/lib/prometheus/metric/boolean.ex
+++ b/lib/prometheus/metric/boolean.ex
@@ -1,130 +1,116 @@
defmodule Prometheus.Metric.Boolean do
@moduledoc """
Boolean metric, to report booleans and flags.
Boolean is a non-standard metric that uses untyped metric underneath.
A Boolean is typically used as a flag i.e. enabled/disabled, online/offline.
Example:
```
-module(my_fuse_instrumenter).
-export([setup/0,
fuse_event/2]).
setup() ->
prometheus_boolean:declare([{name, app_fuse_state},
{labels, [name]}, %% fuse name
{help, "State of various app fuses."}]),
fuse_event(Fuse, Event) ->
case Event of
ok -> prometheus_boolean:set(app_fuse_state, [Fuse], true);
blown -> prometheus_boolean:set(app_fuse_state, [Fuse], false);
_ -> ok
end.
```
"""
use Prometheus.Erlang, :prometheus_boolean
@doc """
Creates a boolean using `spec`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidLabelNameError` if label name is invalid.<br>
Raises `Prometheus.MFAlreadyExistsError` if a boolean with
the same `spec` already exists.
"""
- defmacro new(spec) do
- Erlang.call([spec])
- end
+ delegate new(spec)
@doc """
Creates a boolean using `spec`.
If a boolean with the same `spec` exists returns `false`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidLabelNameError` if label name is invalid.
"""
- defmacro declare(spec) do
- Erlang.call([spec])
- end
+ delegate declare(spec)
@doc """
Sets the boolean identified by `spec` to `value`.
Valid "truthy" values:
- `true`;
- `false`;
- `0` -> false;
- `number > 0` -> true;
- `[]` -> false
- `non-empty list` -> true;
- `:undefined` -> undefined
Other values will generate `Prometheus.InvalidValueError` error.
Raises `Prometheus.InvalidValueError` exception if `value` isn't
a boolean or `:undefined`.<br>
Raises `Prometheus.UnknownMetricError` exception if a boolean for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro set(spec, value) do
- Erlang.metric_call(spec, [value])
- end
+ delegate_metric set(spec, value)
@doc """
Toggles the boolean identified by `spec` to `value`.
Raises `Prometheus.InvalidValueError` exception if boolean is `:undefined`.<br>
Raises `Prometheus.UnknownMetricError` exception if a boolean for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro toggle(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric toggle(spec)
@doc """
Removes boolean series identified by spec.
Raises `Prometheus.UnknownMetricError` exception if a boolean
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro remove(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric remove(spec)
@doc """
Resets the value of the boolean identified by `spec`.
Raises `Prometheus.UnknownMetricError` exception if a boolean
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro reset(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric reset(spec)
@doc """
Returns the value of the boolean identified by `spec`. If there is no boolean for
given labels combination, returns `:undefined`.
Raises `Prometheus.UnknownMetricError` exception if a boolean
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro value(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric value(spec)
end
diff --git a/lib/prometheus/metric/counter.ex b/lib/prometheus/metric/counter.ex
index ecd0495..4c7eeac 100644
--- a/lib/prometheus/metric/counter.ex
+++ b/lib/prometheus/metric/counter.ex
@@ -1,231 +1,219 @@
defmodule Prometheus.Metric.Counter do
@moduledoc """
Counter is a Metric that represents a single numerical value that only ever
goes up. That implies that it cannot be used to count items whose number can
also go down, e.g. the number of currently running processes. Those
"counters" are represented by `Prometheus.Metric.Gauge`.
A Counter is typically used to count requests served, tasks completed, errors
occurred, etc.
Example use cases for Counters:
- Number of requests processed;
- Number of items that were inserted into a queue;
- Total amount of data that a system has processed.
Use the [`rate()`](https://prometheus.io/docs/querying/functions/#rate())/
[`irate()`](https://prometheus.io/docs/querying/functions/#irate())
functions in Prometheus to calculate the rate of increase of a Counter.
By convention, the names of Counters are suffixed by `_total`.
To create a counter use either `new/1` or `declare/1`, the difference is that
`new/` will raise `Prometheus.MFAlreadyExistsError` exception if counter with
the same `registry`, `name` and `labels` combination already exists.
Both accept `spec` `Keyword` with the same set of keys:
- `:registry` - optional, default is `:default`;
- `:name` - required, can be an atom or a string;
- `:help` - required, must be a string;
- `:labels` - optional, default is `[]`.
Example:
```
defmodule MyServiceInstrumenter do
use Prometheus.Metric
## to be called at app/supervisor startup.
## to tolerate restarts use declare.
def setup() do
Counter.declare([name: :my_service_requests_total,
help: "Requests count.",
labels: [:caller]])
end
def inc(caller) do
Counter.inc([name: :my_service_requests_total,
labels: [caller]])
end
end
```
"""
use Prometheus.Erlang, :prometheus_counter
@doc """
Creates a counter using `spec`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidLabelNameError` if label name is invalid.<br>
Raises `Prometheus.MFAlreadyExistsError` if a counter with
the same `spec` already exists.
"""
- defmacro new(spec) do
- Erlang.call([spec])
- end
+ delegate new(spec)
@doc """
Creates a counter using `spec`.
If a counter with the same `spec` exists returns `false`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidLabelNameError` if label name is invalid.
"""
- defmacro declare(spec) do
- Erlang.call([spec])
- end
+ delegate declare(spec)
@doc """
Increments the counter identified by `spec` by `value`.
Raises `Prometheus.InvalidValueError` exception if `value` isn't a positive number.<br>
Raises `Prometheus.UnknownMetricError` exception if a counter
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro inc(spec, value \\ 1) do
- Erlang.metric_call(:inc, spec, [value])
- end
+ delegate_metric inc(spec, value \\ 1)
@doc """
Increments the counter identified by `spec` by 1 when `body` executed.
Read more about bodies: `Prometheus.Injector`.
Raises `Prometheus.UnknownMetricError` exception if a counter
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
defmacro count(spec, body) do
env = __CALLER__
Prometheus.Injector.inject(
fn block ->
quote do
Prometheus.Metric.Counter.inc(unquote(spec), 1)
unquote(block)
end
end,
env,
body
)
end
@doc """
Increments the counter identified by `spec` by 1 when `body` raises `exception`.
Read more about bodies: `Prometheus.Injector`.
Raises `Prometheus.UnknownMetricError` exception if a counter
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
defmacro count_exceptions(spec, exception \\ :_, body) do
env = __CALLER__
Prometheus.Injector.inject(
fn block ->
quote do
require Prometheus.Error
Prometheus.Error.with_prometheus_error(
try do
unquote(block)
rescue
e in unquote(exception) ->
stacktrace =
unquote(
if macro_exported?(Kernel.SpecialForms, :__STACKTRACE__, 0) do
quote(do: __STACKTRACE__)
else
quote(do: System.stacktrace())
end
)
{registry, name, labels} = Prometheus.Metric.parse_spec(unquote(spec))
:prometheus_counter.inc(registry, name, labels, 1)
reraise(e, stacktrace)
end
)
end
end,
env,
body
)
end
@doc """
Increments the counter identified by `spec` by 1 when `body` raises no exceptions.
Read more about bodies: `Prometheus.Injector`.
Raises `Prometheus.UnknownMetricError` exception if a counter
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
defmacro count_no_exceptions(spec, body) do
env = __CALLER__
Prometheus.Injector.inject(
fn block ->
quote do
require Prometheus.Error
try do
unquote(block)
else
value ->
Prometheus.Metric.Counter.inc(unquote(spec), 1)
value
end
end
end,
env,
body
)
end
@doc """
Removes counter series identified by spec.
Raises `Prometheus.UnknownMetricError` exception if a counter
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro remove(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric remove(spec)
@doc """
Resets the value of the counter identified by `spec`.
Raises `Prometheus.UnknownMetricError` exception if a counter
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro reset(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric reset(spec)
@doc """
Returns the value of the counter identified by `spec`. If there is no counter for
given labels combination, returns `:undefined`.
Raises `Prometheus.UnknownMetricError` exception if a counter
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro value(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric value(spec)
end
diff --git a/lib/prometheus/metric/gauge.ex b/lib/prometheus/metric/gauge.ex
index 5da09be..2166821 100644
--- a/lib/prometheus/metric/gauge.ex
+++ b/lib/prometheus/metric/gauge.ex
@@ -1,231 +1,213 @@
defmodule Prometheus.Metric.Gauge do
@moduledoc """
Gauge metric, to report instantaneous values.
Gauge is a metric that represents a single numerical value that can
arbitrarily go up and down.
A Gauge is typically used for measured values like temperatures or current
memory usage, but also "counts" that can go up and down, like the number of
running processes.
Example use cases for Gauges:
- Inprogress requests;
- Number of items in a queue;
- Free memory;
- Total memory;
- Temperature.
Example:
```
defmodule MyPoolInstrumenter do
use Prometheus.Metric
## to be called at app/supervisor startup.
## to tolerate restarts use declare.
def setup() do
Gauge.declare([name: :my_pool_size,
help: "Pool size."])
Gauge.declare([name: :my_pool_checked_out,
help: "Number of sockets checked out from the pool"])
end
def set_size(size) do
Gauge.set([name: :my_pool_size], size)
end
def track_checked_out_sockets(checkout_fun) do
Gauge.track_inprogress([name: :my_pool_checked_out], checkout_fun.())
end
def track_checked_out_sockets_block(socket) do
Gauge.track_inprogress([name: :my_pool_checked_out]) do
# checkout code
socket
end
end
end
```
"""
use Prometheus.Erlang, :prometheus_gauge
@doc """
Creates a gauge using `spec`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidMetricNameError` if label name is invalid.<br>
Raises `Prometheus.InvalidValueError` exception if duration_unit is unknown or
doesn't match metric name.<br>
Raises `Prometheus.MFAlreadyExistsError` if a gauge with the same `spec` exists.
"""
- defmacro new(spec) do
- Erlang.call([spec])
- end
+ delegate new(spec)
@doc """
Creates a gauge using `spec`.
If a gauge with the same `spec` exists returns `false`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidMetricNameError` if label name is invalid.<br>
Raises `Prometheus.InvalidValueError` exception if duration_unit is unknown or
doesn't match metric name.
"""
- defmacro declare(spec) do
- Erlang.call([spec])
- end
+ delegate declare(spec)
@doc """
Sets the gauge identified by `spec` to `value`.
Raises `Prometheus.InvalidValueError` exception if `value` isn't
a number or `:undefined`.<br>
Raises `Prometheus.UnknownMetricError` exception if a gauge for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro set(spec, value) do
- Erlang.metric_call(spec, [value])
- end
+ delegate_metric set(spec, value)
@doc """
Increments the gauge identified by `spec` by `value`.
Raises `Prometheus.InvalidValueError` exception if `value` isn't a number.<br>
Raises `Prometheus.UnknownMetricError` exception if a gauge for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro inc(spec, value \\ 1) do
- Erlang.metric_call(spec, [value])
- end
+ delegate_metric inc(spec, value \\ 1)
@doc """
Decrements the gauge identified by `spec` by `value`.
Raises `Prometheus.InvalidValueError` exception if `value` isn't a number.<br>
Raises `Prometheus.UnknownMetricError` exception if a gauge for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro dec(spec, value \\ 1) do
- Erlang.metric_call(spec, [value])
- end
+ delegate_metric dec(spec, value \\ 1)
@doc """
Sets the gauge identified by `spec` to the current unixtime.
Raises `Prometheus.UnknownMetricError` exception if a gauge
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro set_to_current_time(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric set_to_current_time(spec)
@doc """
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, 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 `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, 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 """
Removes gauge series identified by spec.
Raises `Prometheus.UnknownMetricError` exception if a gauge
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro remove(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric remove(spec)
@doc """
Resets the value of the gauge identified by `spec`.
Raises `Prometheus.UnknownMetricError` exception if a gauge
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro reset(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric reset(spec)
@doc """
Returns the value of the gauge identified by `spec`.
If duration unit set, value will be converted to the duration unit.
[Read more here.](time.html)
Raises `Prometheus.UnknownMetricError` exception if a gauge
for `spec` can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro value(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric value(spec)
end
diff --git a/lib/prometheus/metric/histogram.ex b/lib/prometheus/metric/histogram.ex
index 76ad507..66e03aa 100644
--- a/lib/prometheus/metric/histogram.ex
+++ b/lib/prometheus/metric/histogram.ex
@@ -1,171 +1,159 @@
defmodule Prometheus.Metric.Histogram do
@moduledoc """
A Histogram tracks the size and number of events in buckets.
You can use Histograms for aggregatable calculation of quantiles.
Example use cases for Histograms:
- Response latency;
- Request size.
Histogram expects `buckets` key in a metric spec. Buckets can be:
- a list of numbers in increasing order;
- one of the generate specs (shortcuts for `Prometheus.Buckets` macros)
- `:default`;
- `{:linear, start, step, count}`;
- `{:exponential, start, step, count}`.
Example:
```
defmodule ExampleInstrumenter do
use Prometheus.Metric
## to be called at app/supervisor startup.
## to tolerate restarts use declare.
def setup do
Histogram.new([name: :http_request_duration_milliseconds,
labels: [:method],
buckets: [100, 300, 500, 750, 1000],
help: "Http Request execution time."])
end
def instrument(%{time: time, method: method}) do
Histogram.observe([name: :http_request_duration_milliseconds, labels: [method]],
time)
end
end
```
"""
use Prometheus.Erlang, :prometheus_histogram
@doc """
Creates a histogram using `spec`.
Histogram cannot have a label named "le".
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidMetricNameError` if label name is invalid.<br>
Raises `Prometheus.InvalidValueError` exception if duration_unit is unknown or
doesn't match metric name.<br>
Raises `Prometheus.MFAlreadyExistsError` if a histogram with the same `spec` exists.
Histogram-specific exceptions:
Raises `Prometheus.HistogramNoBucketsError` if buckets are missing, not a list,
empty list or not known buckets spec.<br>
Raises `Prometheus.HistogramInvalidBucketsError` if buckets aren't
in increasing order.<br>
Raises `Prometheus.HistogramInvalidBoundError` if bucket bound isn't a number.
"""
- defmacro new(spec) do
- Erlang.call([spec])
- end
+ delegate new(spec)
@doc """
Creates a histogram using `spec`.
Histogram cannot have a label named "le".
If a histogram with the same `spec` exists returns `false`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidMetricNameError` if label name is invalid.<br>
Raises `Prometheus.InvalidValueError` exception if duration_unit is unknown or
doesn't match metric name.
Histogram-specific exceptions:
Raises `Prometheus.HistogramNoBucketsError` if buckets are missing, not a list,
empty list or not known buckets spec.<br>
Raises `Prometheus.HistogramInvalidBucketsError` if buckets aren't
in increasing order.<br>
Raises `Prometheus.HistogramInvalidBoundError` if bucket bound isn't a number.
"""
- defmacro declare(spec) do
- Erlang.call([spec])
- end
+ delegate declare(spec)
@doc """
Observes the given amount.
Raises `Prometheus.InvalidValueError` exception if `amount` isn't
a number.<br>
Raises `Prometheus.UnknownMetricError` exception if a histogram for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro observe(spec, amount \\ 1) do
- Erlang.metric_call(spec, [amount])
- end
+ delegate_metric observe(spec, amount \\ 1)
@doc """
Observes the amount of time spent executing `body`.
Raises `Prometheus.UnknownMetricError` exception if a histogram 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 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 """
Removes histogram series identified by spec.
Raises `Prometheus.UnknownMetricError` exception if a histogram for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro remove(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric remove(spec)
@doc """
Resets the value of the histogram identified by `spec`.
Raises `Prometheus.UnknownMetricError` exception if a histogram for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro reset(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric reset(spec)
@doc """
Returns the value of the histogram identified by `spec`. If there is no histogram for
given labels combination, returns `:undefined`.
Raises `Prometheus.UnknownMetricError` exception if a histogram for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro value(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric value(spec)
end
diff --git a/lib/prometheus/metric/summary.ex b/lib/prometheus/metric/summary.ex
index 0aa082a..c2922a0 100644
--- a/lib/prometheus/metric/summary.ex
+++ b/lib/prometheus/metric/summary.ex
@@ -1,154 +1,142 @@
defmodule Prometheus.Metric.Summary do
@moduledoc """
Summary metric, to track the size of events.
Example use cases for Summaries:
- Response latency;
- Request size;
- Response size.
Example:
```
defmodule MyProxyInstrumenter do
use Prometheus.Metric
## to be called at app/supervisor startup.
## to tolerate restarts use declare.
def setup() do
Summary.declare([name: :request_size_bytes,
help: "Request size in bytes."])
Summary.declare([name: :response_size_bytes,
help: "Response size in bytes."])
end
def observe_request(size) do
Summary.observe([name: :request_size_bytes], size)
end
def observe_response(size) do
Summary.observe([name: :response_size_bytes], size)
end
end
```
"""
use Prometheus.Erlang, :prometheus_summary
@doc """
Creates a summary using `spec`.
Summary cannot have a label named "quantile".
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidMetricNameError` if label name is invalid.<br>
Raises `Prometheus.InvalidValueError` exception if duration_unit is unknown or
doesn't match metric name.<br>
Raises `Prometheus.MFAlreadyExistsError` if a summary with the same `spec`
already exists.
"""
- defmacro new(spec) do
- Erlang.call([spec])
- end
+ delegate new(spec)
@doc """
Creates a summary using `spec`.
Summary cannot have a label named "quantile".
If a summary with the same `spec` exists returns `false`.
Raises `Prometheus.MissingMetricSpecKeyError` if required `spec` key is missing.<br>
Raises `Prometheus.InvalidMetricNameError` if metric name is invalid.<br>
Raises `Prometheus.InvalidMetricHelpError` if help is invalid.<br>
Raises `Prometheus.InvalidMetricLabelsError` if labels isn't a list.<br>
Raises `Prometheus.InvalidMetricNameError` if label name is invalid;<br>
Raises `Prometheus.InvalidValueError` exception if duration_unit is unknown or
doesn't match metric name.
"""
- defmacro declare(spec) do
- Erlang.call([spec])
- end
+ delegate declare(spec)
@doc """
Observes the given amount.
Raises `Prometheus.InvalidValueError` exception if `amount` isn't a number.<br>
Raises `Prometheus.UnknownMetricError` exception if a summary for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro observe(spec, amount \\ 1) do
- Erlang.metric_call(spec, [amount])
- end
+ delegate_metric observe(spec, amount \\ 1)
@doc """
Observes the amount of time spent executing `body`.
Raises `Prometheus.UnknownMetricError` exception if a summary 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 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 """
Removes summary series identified by spec.
Raises `Prometheus.UnknownMetricError` exception if a summary for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro remove(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric remove(spec)
@doc """
Resets the value of the summary identified by `spec`.
Raises `Prometheus.UnknownMetricError` exception if a summary for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro reset(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric reset(spec)
@doc """
Returns the value of the summary identified by `spec`. If there is no summary for
given labels combination, returns `:undefined`.
If duration unit set, sum will be converted to the duration unit.
[Read more here.](time.html)
Raises `Prometheus.UnknownMetricError` exception if a summary for `spec`
can't be found.<br>
Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
"""
- defmacro value(spec) do
- Erlang.metric_call(spec)
- end
+ delegate_metric value(spec)
end
diff --git a/lib/prometheus/model.ex b/lib/prometheus/model.ex
index cf6e3e0..655e0d7 100644
--- a/lib/prometheus/model.ex
+++ b/lib/prometheus/model.ex
@@ -1,150 +1,128 @@
defmodule Prometheus.Model do
@moduledoc """
Helpers for working with Prometheus data model. For advanced users.
`Prometheus.Collector` example demonstrates how to use this module.
"""
use Prometheus.Erlang, :prometheus_model_helpers
@doc """
Creates Metric Family of `type`, `name` and `help`.
`collector.collect_metrics/2` callback will be called and expected to
return individual metrics list.
"""
- defmacro create_mf(name, help, type, collector, collector_data) do
- Erlang.call([name, help, type, collector, collector_data])
- end
+ delegate create_mf(name, help, type, collector, collector_data)
@doc """
Creates gauge metrics from `mdata` {label, value} tuple list.
iex(11)> Prometheus.Model.gauge_metrics([{[host: "example.com"], 100}])
[{:Metric, [{:LabelPair, "host", "example.com"}], {:Gauge, 100}, :undefined,
:undefined, :undefined, :undefined, :undefined}]
"""
- defmacro gauge_metrics(mdata) do
- Erlang.call([mdata])
- end
+ delegate gauge_metrics(mdata)
@doc """
Creates gauge metric with `labels` and `value`.
iex(13)> Prometheus.Model.gauge_metric([host: "example.com"], 100)
{:Metric, [{:LabelPair, "host", "example.com"}], {:Gauge, 100}, :undefined,
:undefined, :undefined, :undefined, :undefined}
"""
- defmacro gauge_metric(labels \\ [], value) do
- Erlang.call([labels, value])
- end
+ delegate gauge_metric(labels \\ [], value)
@doc """
Creates untyped metrics from `mdata` {label, value} tuple list.
iex(11)> Prometheus.Model.untyped_metrics([{[host: "example.com"], 100}])
[{:Metric, [{:LabelPair, "host", "example.com"}], :undefined,
:undefined, :undefined, {:Untyped, 100}, :undefined, :undefined}]
"""
- defmacro untyped_metrics(mdata) do
- Erlang.call([mdata])
- end
+ delegate untyped_metrics(mdata)
@doc """
Creates untyped metric with `labels` and `value`.
iex(13)> Prometheus.Model.untyped_metric([host: "example.com"], 100)
{:Metric, [{:LabelPair, "host", "example.com"}], :undefined,
:undefined, :undefined, {:Untyped, 100}, :undefined, :undefined}
"""
- defmacro untyped_metric(labels \\ [], value) do
- Erlang.call([labels, value])
- end
+ delegate untyped_metric(labels \\ [], value)
@doc """
Creates counter metrics from `mdata` {labels, value} tuple list.
iex(14)> Prometheus.Model.counter_metrics([{[host: "example.com"], 100}])
[{:Metric, [{:LabelPair, "host", "example.com"}], :undefined, {:Counter, 100},
:undefined, :undefined, :undefined, :undefined}]
"""
- defmacro counter_metrics(mdata) do
- Erlang.call([mdata])
- end
+ delegate counter_metrics(mdata)
@doc """
Creates counter metric with `labels` and `value`.
iex(15)> Prometheus.Model.counter_metric([host: "example.com"], 100)
{:Metric, [{:LabelPair, "host", "example.com"}], :undefined, {:Counter, 100},
:undefined, :undefined, :undefined, :undefined}
"""
- defmacro counter_metric(labels \\ [], value) do
- Erlang.call([labels, value])
- end
+ delegate counter_metric(labels \\ [], value)
@doc """
Creates summary metrics from `mdata` {labels, count, sum} tuple list.
iex(7)> Prometheus.Model.summary_metrics([{[{:method, :get}], 2, 10.5}])
[{:Metric, [{:LabelPair, "method", "get"}], :undefined, :undefined,
{:Summary, 2, 10.5, []}, :undefined, :undefined, :undefined}]
"""
- defmacro summary_metrics(mdata) do
- Erlang.call([mdata])
- end
+ delegate summary_metrics(mdata)
@doc """
Creates summary metric with `labels`, `count`, and `sum`.
iex(3)> Prometheus.Model.summary_metric([{:method, :get}], 2, 10.5)
{:Metric, [{:LabelPair, "method", "get"}], :undefined, :undefined,
{:Summary, 2, 10.5, []}, :undefined, :undefined, :undefined}
"""
- defmacro summary_metric(labels \\ [], count, sum) do
- Erlang.call([labels, count, sum])
- end
+ delegate summary_metric(labels \\ [], count, sum)
@doc """
Creates histogram metrics from `mdata` {labels, buckets, count, sum} tuple list.
iex(2)> Prometheus.Model.histogram_metrics([{[{:method, :get}],
...(2)> [{2, 1}, {5, 1}, {:infinity, 2}],
...(2)> 2, 10.5}])
[{:Metric, [{:LabelPair, "method", "get"}], :undefined, :undefined, :undefined,
:undefined,
{:Histogram, 2, 10.5,
[{:Bucket, 1, 2}, {:Bucket, 1, 5}, {:Bucket, 2, :infinity}]}, :undefined}]
"""
- defmacro histogram_metrics(mdata) do
- Erlang.call([mdata])
- end
+ delegate histogram_metrics(mdata)
@doc """
Creates histogram metric with `labels`, `buckets`, `count`, and `sum`.
iex(4)> Prometheus.Model.histogram_metric([{:method, :get}],
...(4)> [{2, 1}, {5, 1}, {:infinity, 2}],
...(4)> 2, 10.5)
{:Metric, [{:LabelPair, "method", "get"}], :undefined, :undefined, :undefined,
:undefined,
{:Histogram, 2, 10.5,
[{:Bucket, 1, 2}, {:Bucket, 1, 5}, {:Bucket, 2, :infinity}]}, :undefined}
Buckets is a list of pairs {upper_bound, cumulative_count}.
Cumulative count is a sum of all cumulative_counts of previous buckets + counter of
current bucket.
"""
- defmacro histogram_metric(labels \\ [], buckets, count, sum) do
- Erlang.call([labels, buckets, count, sum])
- end
+ delegate histogram_metric(labels \\ [], buckets, count, sum)
end
diff --git a/lib/prometheus/registry.ex b/lib/prometheus/registry.ex
index b81a1a6..a18515f 100644
--- a/lib/prometheus/registry.ex
+++ b/lib/prometheus/registry.ex
@@ -1,73 +1,57 @@
defmodule Prometheus.Registry do
@moduledoc """
A registry of Collectors.
The majority of users should use the `:default`, rather than their own.
Creating a registry other than the default is primarily useful for
unit tests, or pushing a subset of metrics to the
[Pushgateway](https://github.com/prometheus/pushgateway) from batch jobs.
"""
use Prometheus.Erlang, :prometheus_registry
@doc """
Tries to find registry with the `name`.
Assumes that registry name is always an atom.
If `Name` is an atom `ets:lookup/2` is used
If `Name` is an iolist performs safe search (to avoid interning
atoms) and returns atom or false. This operation is O(n).
"""
- defmacro exists(name) do
- Erlang.call([name])
- end
+ delegate exists(name)
@doc """
Calls `callback` for each collector with two arguments: `registry` and `collector`.
"""
- defmacro collect(callback, registry \\ :default) do
- Erlang.call([registry, callback])
- end
+ delegate collect(callback, registry \\ :default)
@doc """
Returns collectors registered in `registry`.
"""
- defmacro collectors(registry \\ :default) do
- Erlang.call([registry])
- end
+ delegate collectors(registry \\ :default)
@doc """
Registers a collector.
"""
- defmacro register_collector(registry \\ :default, collector) do
- Erlang.call([registry, collector])
- end
+ delegate register_collector(registry \\ :default, collector)
@doc """
Registers collectors list.
"""
- defmacro register_collectors(registry \\ :default, collectors) do
- Erlang.call([registry, collectors])
- end
+ delegate register_collectors(registry \\ :default, collectors)
@doc """
Unregisters a collector.
"""
- defmacro deregister_collector(registry \\ :default, collector) do
- Erlang.call([registry, collector])
- end
+ delegate deregister_collector(registry \\ :default, collector)
@doc """
Unregisters all collectors.
"""
- defmacro clear(registry \\ :default) do
- Erlang.call([registry])
- end
+ delegate clear(registry \\ :default)
@doc """
Checks whether `collector` is registered.
"""
- defmacro collector_registered?(registry \\ :default, collector) do
- Erlang.call(:collector_registeredp, [registry, collector])
- end
+ delegate collector_registered?(registry \\ :default, collector), as: :collector_registeredp
end

File Metadata

Mime Type
text/x-diff
Expires
Tue, Nov 26, 6:06 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40217
Default Alt Text
(54 KB)

Event Timeline