Page MenuHomePhorge

No OneTemporary

Size
199 KB
Referenced Files
None
Subscribers
None
diff --git a/bin/increment-version b/bin/increment-version
index 169ffae..233b6e7 100755
--- a/bin/increment-version
+++ b/bin/increment-version
@@ -1,95 +1,95 @@
#!/bin/bash
# Based on https://github.com/fmahnke/shell-semver
# The MIT License (MIT)
# Copyright (c) 2014 Fritz Mahnke
# Increment a version string using Semantic Versioning (SemVer) terminology.
# Parse command line options.
while getopts ":Mmpa:" Option
do
case $Option in
M ) major=true;;
m ) minor=true;;
p ) patch=true;;
a ) alpha=${OPTARG};;
esac
done
shift $(($OPTIND - 1))
STAGED_COUNT=$(git diff --cached --numstat | wc -l)
UNSTAGED_COUNT=$(git diff --numstat | wc -l)
## TODO check we are on master
if [ $STAGED_COUNT -ne "0" ]; then
echo "you have staged changes. Aborting".
exit 1
fi
if [ $UNSTAGED_COUNT -ne "0" ]; then
echo "you have unstaged changes. Aborting".
exit 1
fi
version="$(mix run --no-compile --no-start -e ":io.format('~s', [PrometheusEx.Mixfile.project()[:version]])")"
echo "Old version: ${version}"
# Build array from version string.
oa=( ${version//./ } )
a=( ${version//./ } )
# If version string is missing or has the wrong number of members, show usage message.
if [ ${#a[@]} -ne 3 ]
then
echo "usage: $(basename $0) [-Mmp] TAG_MESSAGE(optional)"
exit 1
fi
# Increment version numbers as requested.
if [ ! -z $major ]
then
((a[0]++))
a[1]=0
a[2]=0
fi
if [ ! -z $minor ]
then
((a[1]++))
a[2]=0
fi
if [ ! -z $patch ]
then
((a[2]++))
fi
if [ -z ${alpha+x} ];
then
new_version="${a[0]}.${a[1]}.${a[2]}";
else
new_version="${a[0]}.${a[1]}.${a[2]}.alpha-$alpha";
fi
echo "New version: ${new_version}"
-sed -i s/\"${oa[0]}\.${oa[1]}\.${oa[2]}\"/\"${a[0]}\.${a[1]}\.${a[2]}\"/g mix.exs
+sed -i s/\"${oa[0]}\.${oa[1]}\.${oa[2]}\"/\"$new_version\"/g mix.exs
sed -i s/\~\>\ ${oa[0]}\.${oa[1]}/\~\>\ ${a[0]}\.${a[1]}/g README.md
git add mix.exs
git add README.md
git add doc
git commit -m "Bump to v${new_version}"
TAG_MESSAGE=${1:-"New version: v${new_version}"}
git tag -a "v${new_version}" -m "${TAG_MESSAGE}"
git push origin master
git push origin "v${new_version}"
mix hex.publish
diff --git a/lib/prometheus.ex b/lib/prometheus.ex
index 901ac30..8eff2f5 100644
--- a/lib/prometheus.ex
+++ b/lib/prometheus.ex
@@ -1,119 +1,117 @@
defmodule Prometheus do
- @moduledoc"""
+ @moduledoc """
[Prometheus.io](https://prometheus.io) client library powered by
[prometheus.erl](https://hexdocs.pm/prometheus)
Prometheus.ex is a thin, mostly macro-based wrapper around prometheus.erl.
While it's pretty straightforward to use prometheus.erl from Elixir,
you might prefer prometheus.ex because it gives you:
- native Elixir syntax;
- native Elixir exceptions;
- configuration helpers that are really handy if you plan to write your custom
instrumenter.
```elixir
defmodule ExampleInstrumenter do
use Prometheus ## require common Prometheus modules, also alias metrics.
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
```
## Integrations
- [Ecto Instrumenter](https://hex.pm/packages/prometheus_ecto);
- [Elixir plugs Instrumenters and Exporter](https://hex.pm/packages/prometheus_plugs);
- [Fuse plugin](https://github.com/jlouis/fuse#fuse_stats_prometheus)
- [OS process info Collector](https://hex.pm/packages/prometheus_process_collector)
(linux-only);
- [Phoenix Instrumenter](https://hex.pm/packages/prometheus_phoenix);
- [RabbitMQ Exporter](https://github.com/deadtrickster/prometheus_rabbitmq_exporter).
## Erlang VM Collectors
- [Memory Collector](vm-memory-collector.html);
- [Statistics Collector](vm-statistics-collector.html);
- [System Information Collector](vm-system-info-collector.html).
## API
API can be grouped like this:
### Standard Metrics & Registry
- `Prometheus.Metric.Counter` - counter metric, to track counts of events or running
totals;
- `Prometheus.Metric.Gauge` - gauge metric, to report instantaneous values;
- `Prometheus.Metric.Histogram` - histogram metric, to track distributions of events;
- `Prometheus.Metric.Summary` - summary metric, to track the size of events;
- `Prometheus.Registry` - working with Prometheus registries.
All metrics created via `new/1` or `declare/1` macros. The difference is that `new/1`
actually wants metric to be new and raises `Prometheus.MFAlreadyExistsError`
if it isn't.
Both `new/1` and `declare/1` accept options as
[Keyword](http://elixir-lang.org/docs/stable/elixir/Keyword.html).
Common options are:
- name - metric name, can be an atom or a string (required);
- help - metric help, string (required);
- labels - metric labels, label can be an atom or a string (default is []);
- registry - Prometheus registry for the metric, can be any term. (default is :default)
Histogram also accepts `buckets` option. Please refer to respective modules docs
for the more information.
### General Helpers
- `Prometheus.Buckets` - linear or exponential bucket generators;
- `Prometheus.Contrib.HTTP` - helpers for HTTP instrumenters.
### Integration Helpers
- `Prometheus.Config` - provides standard configuration mechanism
for custom instrumenters/exporters.
### Exposition Formats
- `Prometheus.Format.Text` - renders metrics for a given registry
(default is `:default`) in text format;
- `Prometheus.Format.Protobuf` - renders metrics for a given registry
(default is `:default`) in protobuf v2 format.
### Advanced
You will need this modules only if you're writing custom collector for app/lib
that can't be instrumented directly.
- `Prometheus.Collector` - exports macros for managing/creating collectors;
- `Prometheus.Model` - provides API for working with underlying Prometheus models.
You'll use that if you want to create custom collector.
"""
defmacro __using__(_opts) do
-
quote do
require Prometheus.Collector
require Prometheus.Registry
require Prometheus.Buckets
use Prometheus.Metric
require Prometheus.Contrib.HTTP
require Prometheus.Contrib.Mnesia
end
end
-
end
diff --git a/lib/prometheus/buckets.ex b/lib/prometheus/buckets.ex
index ff85427..b1973f5 100644
--- a/lib/prometheus/buckets.ex
+++ b/lib/prometheus/buckets.ex
@@ -1,53 +1,21 @@
defmodule Prometheus.Buckets do
@moduledoc """
Histogram buckets generators.
"""
use Prometheus.Erlang, :prometheus_buckets
@doc """
- Default histogram buckets:
+ 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(2)> Prometheus.Buckets.default()
- [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]
+ iex(3)> Prometheus.Buckets.new({:exponential, 100, 1.2, 3})
+ [100, 120, 144, :infinity]
- Please note these buckets are floats and represent seconds so you'll have to use
- `Prometheus.Metric.Histogram.dobserve/2` or configure duration_unit as `:seconds`.
-
- """
- defmacro default do
- Erlang.call()
- end
-
- @doc """
- Creates `count` buckets, where the lowest bucket has an
- upper bound of `start` and each following bucket's upper bound is `factor`
- times the previous bucket's upper bound. The returned list is meant to be
- used for the `:buckets` key of histogram constructors options.
-
- iex(2)> Prometheus.Buckets.exponential(100, 1.2, 3)
- [100, 120, 144]
-
- The function raises `Prometheus.InvalidValueError` if `count` is 0 or negative,
- if `start` is 0 or negative, or if `factor` is less than or equals to 1.
+ iex(2)> Prometheus.Buckets.new({:linear, 10, 5, 6})
+ [10, 15, 20, 25, 30, 35, :infinity]
"""
- defmacro exponential(start, factor, count) do
- Erlang.call([start, factor, count])
+ defmacro new(arg) do
+ Erlang.call([arg])
end
-
- @doc """
- Creates `count` buckets, each `width` wide, where the lowest
- bucket has an upper bound of `start`. The returned list is meant to be
- used for the `:buckets` key of histogram constructors options.
-
- iex(2)> Prometheus.Buckets.linear(10, 5, 6)
- [10, 15, 20, 25, 30, 35]
-
- The function raises `Prometheus.InvalidValueError` exception
- if `count` is zero or negative.
- """
- defmacro linear(start, step, count) do
- Erlang.call([start, step, count])
- end
-
end
diff --git a/lib/prometheus/collector.ex b/lib/prometheus/collector.ex
index 9071cc0..b3d4bf8 100644
--- a/lib/prometheus/collector.ex
+++ b/lib/prometheus/collector.ex
@@ -1,94 +1,90 @@
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]
-
+ 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
-
end
diff --git a/lib/prometheus/config.ex b/lib/prometheus/config.ex
index 97ac266..76d9408 100644
--- a/lib/prometheus/config.ex
+++ b/lib/prometheus/config.ex
@@ -1,91 +1,93 @@
defmodule Prometheus.Config do
-
@moduledoc """
Configuration templates for custom collectors/exporters.
When `use`ed, generates accessor for each configuration option:
iex(4)> defmodule MyInstrumenter do
...(4)> use Prometheus.Config, [:required_option,
...(4)> registry: :default]
...(4)> end
iex(5)> MyInstrumenter.Config.registry(MyInstrumenter)
:default
iex(6)> MyInstrumenter.Config.required_option!(MyInstrumenter)
** (Prometheus.Config.KeyNotFoundError) mandatory option :required_option not found in PrometheusTest.MyInstrumenter instrumenter/collector config
iex(7)> Application.put_env(:prometheus, MyInstrumenter,
...(7)> [required_option: "Hello world!"])
:ok
iex(8)> MyInstrumenter.Config.required_option!(MyInstrumenter)
"Hello world!"
"""
defmodule KeyNotFoundError do
@moduledoc """
Raised when mandatory configuration option not found in app env.
"""
defexception [:option, :key]
def message(%{option: option, key: key}) do
friendly_key_name = String.replace_leading("#{key}", "Elixir.", "")
+
"mandatory option :#{option} not found" <>
" in #{friendly_key_name} instrumenter/collector config"
end
end
defmacro __using__(default_config) do
-
- keyword_default_config = Enum.reject(default_config, fn(option) ->
- case option do
- {_, _} -> false
- _ -> true
- end
- end)
+ keyword_default_config =
+ Enum.reject(default_config, fn option ->
+ case option do
+ {_, _} -> false
+ _ -> true
+ end
+ end)
quote do
defmodule Config do
@moduledoc false
def config(key) do
Application.get_env(:prometheus, key, unquote(keyword_default_config))
end
defp config(key, option, default) do
key
|> config()
|> Keyword.get(option, default)
end
defp config(key, option) do
key
|> config()
|> Keyword.fetch!(option)
rescue
- # credo:disable-for-next-line Credo.Check.Warning.RaiseInsideRescue
- e in KeyError -> raise %KeyNotFoundError{key: key, option: option}
+ e in KeyError ->
+ # credo:disable-for-next-line Credo.Check.Warning.RaiseInsideRescue
+ raise %KeyNotFoundError{key: key, option: option}
end
unquote do
for config <- default_config do
case config do
{option, default} ->
quote do
def unquote(option)(key) do
config(key, unquote(option), unquote(default))
end
end
+
option ->
quote do
def unquote(:"#{option}!")(key) do
config(key, unquote(option))
end
end
end
end
end
end
end
end
end
diff --git a/lib/prometheus/contrib/http.ex b/lib/prometheus/contrib/http.ex
index 26986d7..694c6a3 100644
--- a/lib/prometheus/contrib/http.ex
+++ b/lib/prometheus/contrib/http.ex
@@ -1,34 +1,32 @@
defmodule Prometheus.Contrib.HTTP do
@moduledoc """
HTTP instrumentation helpers
"""
@doc """
Returns default microseconds buckets for measuring http requests duration:
iex(6)> Prometheus.Contrib.HTTP.microseconds_duration_buckets
[10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 25000, 50000,
100000, 250000, 500000, 1000000, 2500000, 5000000, 10000000]
"""
defmacro microseconds_duration_buckets do
- :prometheus_http.microseconds_duration_buckets
+ :prometheus_http.microseconds_duration_buckets()
end
@doc """
Returns class of the http status code:
iex(7)> Prometheus.Contrib.HTTP.status_class(202)
'success'
Raises `Prometheus.InvalidValueError` exception if `code` is not a positive integer.
"""
defmacro status_class(code) do
quote do
require Prometheus.Error
- Prometheus.Error.with_prometheus_error(
- :prometheus_http.status_class(unquote(code))
- )
+ Prometheus.Error.with_prometheus_error(:prometheus_http.status_class(unquote(code)))
end
end
end
diff --git a/lib/prometheus/contrib/mnesia.ex b/lib/prometheus/contrib/mnesia.ex
index c333b09..5bdcec2 100644
--- a/lib/prometheus/contrib/mnesia.ex
+++ b/lib/prometheus/contrib/mnesia.ex
@@ -1,35 +1,40 @@
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
+ defmacro table_disk_size(
+ dir \\ quote do
+ :mnesia.system_info(:directory)
+ end,
+ table
+ ) do
Erlang.call([dir, table])
end
@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
end
diff --git a/lib/prometheus/erlang.ex b/lib/prometheus/erlang.ex
index 7a10f02..2de0043 100644
--- a/lib/prometheus/erlang.ex
+++ b/lib/prometheus/erlang.ex
@@ -1,135 +1,153 @@
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)))
-
+ unquote(module).unquote(function)(unquote_splicing(arguments))
+ )
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))
+ 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
Prometheus.Error.with_prometheus_error(
- unquote(module).unquote(function)(unquote(registry), unquote(name),
- unquote(labels), unquote_splicing(arguments)))
-
+ unquote(module).unquote(function)(
+ unquote(registry),
+ unquote(name),
+ unquote(labels),
+ unquote_splicing(arguments)
+ )
+ )
end
+
_ ->
quote do
-
require Prometheus.Error
{registry, name, labels} = Metric.parse_spec(unquote(spec))
Prometheus.Error.with_prometheus_error(
- unquote(module).unquote(function)(registry, name, labels,
- unquote_splicing(arguments)))
-
+ 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}
+ {_, _} ->
+ {mf_or_spec, spec, arguments}
+
## Erlang.metric_call(:inc, spec, [value])
- _ when is_atom(mf_or_spec) -> {mf_or_spec, spec, arguments}
+ _ 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
end
end
defp parse_mfa(__CALLER__, mf, arguments) do
- arguments = case mf do
- _ when is_list(mf) ->
- [] = arguments
- mf
- _ ->
- arguments
- end
-
- {module, function} = case mf do
- false ->
- {f, _arity} = __CALLER__.function
- {Module.get_attribute(__CALLER__.module, :erlang_module), f}
- _ when is_list(mf) ->
- {f, _arity} = __CALLER__.function
- {Module.get_attribute(__CALLER__.module, :erlang_module), f}
- {_, _} ->
- mf
- _ when is_atom(mf) ->
- {Module.get_attribute(__CALLER__.module, :erlang_module), mf}
- end
+ arguments =
+ case mf do
+ _ when is_list(mf) ->
+ [] = arguments
+ mf
+
+ _ ->
+ arguments
+ end
+
+ {module, function} =
+ case mf do
+ false ->
+ {f, _arity} = __CALLER__.function
+ {Module.get_attribute(__CALLER__.module, :erlang_module), f}
+
+ _ when is_list(mf) ->
+ {f, _arity} = __CALLER__.function
+ {Module.get_attribute(__CALLER__.module, :erlang_module), f}
+
+ {_, _} ->
+ mf
+
+ _ when is_atom(mf) ->
+ {Module.get_attribute(__CALLER__.module, :erlang_module), mf}
+ 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/error.ex b/lib/prometheus/error.ex
index 62e0037..749dc22 100644
--- a/lib/prometheus/error.ex
+++ b/lib/prometheus/error.ex
@@ -1,206 +1,220 @@
defmodule Prometheus.InvalidValueError do
@moduledoc """
Raised when given `value` is invalid i.e. when you pass a negative number to
`Prometheus.Metric.Counter.inc/2`.
"""
defexception [:value, :orig_message]
def message(%{value: value, orig_message: message}) do
- "Invalid value: #{inspect value} (#{message})."
+ "Invalid value: #{inspect(value)} (#{message})."
end
end
defmodule Prometheus.InvalidMetricNameError do
@moduledoc """
Raised when given metric `name` is invalid i.e. can't be represented as printable utf-8
string that matches `^[a-zA-Z_:][a-zA-Z0-9_:]*$` regular expression.
"""
defexception [:name]
def message(%{name: name}) do
"Invalid metric name: #{name}."
end
end
defmodule Prometheus.InvalidMetricLabelsError do
@moduledoc """
Raised when `labels` isn't a list.
"""
defexception [:labels]
def message(%{labels: labels}) do
"Invalid metric labels: #{labels}."
end
end
defmodule Prometheus.InvalidMetricHelpError do
@moduledoc """
Raised when given metric `help` is invalid i.e. isn't a printable utf-8 string.
"""
defexception [:help]
def message(%{help: help}) do
"Invalid metric help: #{help}."
end
end
defmodule Prometheus.InvalidMetricArityError do
@moduledoc """
Raised when metric arity is invalid e.g. counter metric was created with two labels but
only one label value is passed to `Prometheus.Metric.Counter.inc/2`.
"""
defexception [:present, :expected]
def message(%{present: present, expected: expected}) do
"Invalid metric arity: got #{present}, expected #{expected}."
end
end
defmodule Prometheus.UnknownMetricError do
defexception [:registry, :name]
def message(%{registry: registry, name: name}) do
"Unknown metric {registry: #{registry}, name: #{name}}."
end
end
defmodule Prometheus.InvalidLabelNameError do
@moduledoc """
Raised when label `name` is invalid i.e. can't be represented as printable utf-8 string
that matches `^[a-zA-Z_][a-zA-Z0-9_]*$` regular expression or starts with `__`.
Metric can impose further restrictions on label names.
"""
defexception [:name, :orig_message]
def message(%{name: name, orig_message: message}) do
"Invalid label name: #{name} (#{message})."
end
end
defmodule Prometheus.MFAlreadyExistsError do
@moduledoc """
Raised when one tries to create metric in `registry` with `name` it already exists.
"""
defexception [:registry, :name]
def message(%{registry: registry, name: name}) do
"Metric #{registry}:#{name} already exists."
end
end
-defmodule Prometheus.HistogramNoBucketsError do
+defmodule Prometheus.NoBucketsError do
@moduledoc """
Raised by histogram constructors when buckets can't be found in spec, or
found value is empty list.
"""
defexception [:buckets]
def message(%{buckets: buckets}) do
"Invalid histogram buckets: #{buckets}."
end
end
-defmodule Prometheus.HistogramInvalidBucketsError do
+defmodule Prometheus.InvalidBucketsError do
@moduledoc """
Raised by histogram constructors when buckets are invalid i.e. not sorted in increasing
order or generator spec is unknown.
"""
defexception [:buckets, :orig_message]
def message(%{buckets: buckets, orig_message: message}) do
buckets = :io_lib.format("~p", [buckets])
"Invalid histogram buckets: #{buckets} (#{message})."
end
end
-defmodule Prometheus.HistogramInvalidBoundError do
+defmodule Prometheus.InvalidBoundError do
@moduledoc """
Raised by histogram constructors when bucket bound isn't a number.
"""
defexception [:bound]
def message(%{bound: bound}) do
"Invalid histogram bound: #{bound}."
end
end
defmodule Prometheus.MissingMetricSpecKeyError do
@moduledoc """
Raised when required metric `spec` `key` is missing. All metrics
require at least `name` and when metric created `help`.
Metrics can have their specific required keys.
"""
defexception [:key, :spec]
def message(%{key: key}) do
"Required key #{key} is missing from metric spec."
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
# credo:disable-for-this-file Credo.Check.Refactor.ABCSize
# credo:disable-for-this-file Credo.Check.Refactor.CyclomaticComplexity
def normalize(erlang_error) do
case erlang_error do
%ErlangError{original: original} ->
case original do
{:invalid_value, value, message} ->
%Prometheus.InvalidValueError{value: value, orig_message: message}
+
{:invalid_metric_name, name, _message} ->
%Prometheus.InvalidMetricNameError{name: name}
+
{:invalid_metric_help, help, _message} ->
%Prometheus.InvalidMetricHelpError{help: help}
+
{:invalid_metric_arity, present, expected} ->
%Prometheus.InvalidMetricArityError{present: present, expected: expected}
+
{:unknown_metric, registry, name} ->
%Prometheus.UnknownMetricError{registry: registry, name: name}
+
{:invalid_metric_labels, labels, _message} ->
%Prometheus.InvalidMetricLabelsError{labels: labels}
+
{:invalid_metric_label_name, name, message} ->
%Prometheus.InvalidLabelNameError{name: name, orig_message: message}
+
{:mf_already_exists, {registry, name}, _message} ->
%Prometheus.MFAlreadyExistsError{registry: registry, name: name}
- {:histogram_no_buckets, buckets} ->
- %Prometheus.HistogramNoBucketsError{buckets: buckets}
- {:histogram_invalid_buckets, buckets, message} ->
- %Prometheus.HistogramInvalidBucketsError{buckets: buckets,
- orig_message: message}
- {:histogram_invalid_bound, bound} ->
- %Prometheus.HistogramInvalidBoundError{bound: bound}
+
+ {:no_buckets, buckets} ->
+ %Prometheus.NoBucketsError{buckets: buckets}
+
+ {:invalid_buckets, buckets, message} ->
+ %Prometheus.InvalidBucketsError{
+ buckets: buckets,
+ orig_message: message
+ }
+
+ {:invalid_bound, bound} ->
+ %Prometheus.InvalidBoundError{bound: bound}
+
{:missing_metric_spec_key, key, spec} ->
%Prometheus.MissingMetricSpecKeyError{key: key, spec: spec}
+
_ ->
erlang_error
end
+
_ ->
erlang_error
end
end
defmacro with_prometheus_error(block) do
quote do
try do
unquote(block)
rescue
- e in ErlangError -> reraise Prometheus.Error.normalize(e), System.stacktrace
+ e in ErlangError -> reraise Prometheus.Error.normalize(e), System.stacktrace()
end
end
end
-
end
diff --git a/lib/prometheus/format/protobuf.ex b/lib/prometheus/format/protobuf.ex
index 1fb4b40..1399551 100644
--- a/lib/prometheus/format/protobuf.ex
+++ b/lib/prometheus/format/protobuf.ex
@@ -1,28 +1,23 @@
defmodule Prometheus.Format.Protobuf do
@moduledoc """
Serializes Prometheus registry using [protocol buffer format](http://bit.ly/2cxSuJP).
"""
require Prometheus.Error
@doc """
Content type of protocol buffer format.
"""
def content_type do
require Prometheus.Error
- Prometheus.Error.with_prometheus_error(
- :prometheus_protobuf_format.content_type
- )
+ Prometheus.Error.with_prometheus_error(:prometheus_protobuf_format.content_type())
end
@doc """
Format `registry` (default is `:default`) using protocol buffer format.
"""
def format(registry \\ :default) do
require Prometheus.Error
- Prometheus.Error.with_prometheus_error(
- :prometheus_protobuf_format.format(registry)
- )
+ Prometheus.Error.with_prometheus_error(:prometheus_protobuf_format.format(registry))
end
-
end
diff --git a/lib/prometheus/format/text.ex b/lib/prometheus/format/text.ex
index 3a886a7..395e602 100644
--- a/lib/prometheus/format/text.ex
+++ b/lib/prometheus/format/text.ex
@@ -1,41 +1,36 @@
defmodule Prometheus.Format.Text do
@moduledoc """
Serializes Prometheus registry using the latest [text format](http://bit.ly/2cxSuJP).
Example output:
```
# TYPE http_request_duration_milliseconds histogram
# HELP http_request_duration_milliseconds Http Request execution time
http_request_duration_milliseconds_bucket{method="post",le="100"} 0
http_request_duration_milliseconds_bucket{method="post",le="300"} 1
http_request_duration_milliseconds_bucket{method="post",le="500"} 3
http_request_duration_milliseconds_bucket{method="post",le="750"} 4
http_request_duration_milliseconds_bucket{method="post",le="1000"} 5
http_request_duration_milliseconds_bucket{method="post",le="+Inf"} 6
http_request_duration_milliseconds_count{method="post"} 6
http_request_duration_milliseconds_sum{method="post"} 4350
```
"""
require Prometheus.Error
@doc """
Returns content type of the latest text format.
"""
def content_type do
require Prometheus.Error
- Prometheus.Error.with_prometheus_error(
- :prometheus_text_format.content_type
- )
+ Prometheus.Error.with_prometheus_error(:prometheus_text_format.content_type())
end
@doc """
Formats `registry` (default is `:default`) using the latest text format.
"""
def format(registry \\ :default) do
require Prometheus.Error
- Prometheus.Error.with_prometheus_error(
- :prometheus_text_format.format(registry)
- )
+ Prometheus.Error.with_prometheus_error(:prometheus_text_format.format(registry))
end
-
end
diff --git a/lib/prometheus/injector.ex b/lib/prometheus/injector.ex
index c5083fe..0881fa6 100644
--- a/lib/prometheus/injector.ex
+++ b/lib/prometheus/injector.ex
@@ -1,94 +1,110 @@
defmodule Prometheus.Injector do
-
def inject(callback, env, ast) do
ast
- |> Macro.prewalk(fn (thing) ->
+ |> Macro.prewalk(fn thing ->
case thing do
- {:def, _, _} = defun -> defun
- {:in, _, _} = arrow -> arrow #otherwise e in RuntimeError will be rewritten
- _ -> Macro.expand(thing, env)
+ {:def, _, _} = defun ->
+ defun
+
+ # otherwise e in RuntimeError will be rewritten
+ {:in, _, _} = arrow ->
+ arrow
+
+ _ ->
+ Macro.expand(thing, env)
end
end)
- |> inject_(callback)
+ |> inject_(callback)
end
# lambda
def inject_({:fn, fn_meta, [{:->, arrow_meta, [args, do_block]}]}, callback) do
case args do
[] ->
- callback.({{:., [],
- [{:fn, fn_meta,
- [{:->, arrow_meta,
- [[], do_block]}]}]}, [],
- []})
+ callback.(
+ {{:., [], [{:fn, fn_meta, [{:->, arrow_meta, [[], do_block]}]}]}, [], []}
+ )
+
_ ->
- names = args
- |> Enum.map(fn({name, _, _}) -> name end)
+ names =
+ args
+ |> Enum.map(fn {name, _, _} -> name end)
+
raise Prometheus.InvalidBlockArityError, args: names
end
end
# do_blocks can be simple calls or defs
def inject_([{:do, {:__block__, [], do_blocks}}], callback) do
do_blocks = List.flatten(do_blocks)
+
if have_defs(do_blocks) do
Enum.map(do_blocks, &inject_to_def(&1, callback))
else
- callback.({:__block__, [], do_blocks})
+ callback.({:__block__, [], do_blocks})
end
end
# just do
def inject_([{:do, do_block}], callback) do
inject_([{:do, {:__block__, [], [do_block]}}], callback)
end
# implicit try
def inject_([{:do, _do_block} | rest] = all, callback) do
if is_try_unwrapped(rest) do
callback.(
quote do
try unquote(all)
- end)
+ end
+ )
else
- raise "Unexpected do block #{inspect rest}"
+ raise "Unexpected do block #{inspect(rest)}"
end
end
# single do, or other non-block stuff like function calls
def inject_(thing, callback) do
inject_([{:do, {:__block__, [], [thing]}}], callback)
end
defp is_try_unwrapped(block) do
- Keyword.has_key?(block, :catch)
- || Keyword.has_key?(block, :rescue)
- || Keyword.has_key?(block, :after)
- || Keyword.has_key?(block, :else)
+ Keyword.has_key?(block, :catch) || Keyword.has_key?(block, :rescue) ||
+ Keyword.has_key?(block, :after) || Keyword.has_key?(block, :else)
end
defp have_defs(blocks) do
- defs_count = Enum.count(blocks, fn
- ({:def, _, _}) -> true
- (_) -> false
- end)
+ defs_count =
+ Enum.count(blocks, fn
+ {:def, _, _} -> true
+ _ -> false
+ end)
blocks_count = Enum.count(blocks)
case defs_count do
0 -> false
^blocks_count -> true
_ -> raise "Mixing defs and other blocks isn't allowed"
end
end
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
- {:def, def_meta, [head, [do: callback.(
- quote do
- try unquote(all)
- end)]]}
+ {:def, def_meta,
+ [
+ head,
+ [
+ do:
+ callback.(
+ quote do
+ try unquote(all)
+ end
+ )
+ ]
+ ]}
end
end
diff --git a/lib/prometheus/metric.ex b/lib/prometheus/metric.ex
index fe5f9ab..50ead0a 100644
--- a/lib/prometheus/metric.ex
+++ b/lib/prometheus/metric.ex
@@ -1,157 +1,176 @@
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_laod` callback, metrics will be declared
iff the callback returns `:ok`.
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}
+ 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.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)
+ Module.register_attribute(
+ unquote(module_name),
+ unquote(metric),
+ accumulate: true
+ )
end
- end)
+ end
+ )
@before_compile unquote(__MODULE__)
end
end
defmacro __before_compile__(env) do
quote do
def __declare_prometheus_metrics__() do
if List.keymember?(Application.started_applications(), :prometheus, 0) do
- unquote_splicing(
- for metric <- @metrics do
- declarations = Module.get_attribute(env.module, metric)
- Module.delete_attribute(env.module, metric)
- quote do
- unquote_splicing(
- for params <- declarations do
- emit_create_metric(metric, params)
- end)
- :ok
- end
- end)
+ (unquote_splicing(
+ for metric <- @metrics do
+ declarations = Module.get_attribute(env.module, metric)
+ Module.delete_attribute(env.module, metric)
+
+ quote do
+ unquote_splicing(
+ for params <- declarations do
+ emit_create_metric(metric, params)
+ end
+ )
+
+ :ok
+ end
+ end
+ ))
else
: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)}"
+ "expected the @on_load attribute to be an atom or a " <>
+ "{atom, 0} tuple, got: #{inspect(other)}"
end
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/counter.ex b/lib/prometheus/metric/counter.ex
index 874c550..b524424 100644
--- a/lib/prometheus/metric/counter.ex
+++ b/lib/prometheus/metric/counter.ex
@@ -1,222 +1,223 @@
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
@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
@doc """
Increments the counter identified by `spec` by `value`.
- Raises `Prometheus.InvalidValueError` exception if `value` isn't a positive integer.<br>
+ 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
@doc """
Increments the counter identified by `spec` by 1 when `body` executed.
Read more about bodies: `Prometheus.Injector`.
- Raises `Prometheus.InvalidValueError` exception if `value` isn't a positive integer.<br>
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)
+
+ 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.InvalidValueError` exception if `value` isn't a positive integer.<br>
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 = System.stacktrace()
- {registry, name, labels} = Prometheus.Metric.parse_spec(unquote(spec))
- :prometheus_counter.inc(registry, name, labels, 1)
- reraise(e, stacktrace)
- end)
- end
- end, env, body)
+
+ 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 = System.stacktrace()
+ {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.InvalidValueError` exception if `value` isn't a positive integer.<br>
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 """
- Increments the counter identified by `spec` by `value`.
- If `value` happened to be a float number even one time(!) you
- shouldn't use `inc/2` after dinc.
+ Prometheus.Injector.inject(
+ fn block ->
+ quote do
+ require Prometheus.Error
- 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 dinc(spec, value \\ 1) do
- Erlang.metric_call({:prometheus_counter, :dinc}, spec, [value])
+ 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
@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
@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
end
diff --git a/lib/prometheus/metric/gauge.ex b/lib/prometheus/metric/gauge.ex
index 1760b53..5da09be 100644
--- a/lib/prometheus/metric/gauge.ex
+++ b/lib/prometheus/metric/gauge.ex
@@ -1,247 +1,231 @@
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
@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
@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
@doc """
Increments the gauge identified by `spec` by `value`.
- Raises `Prometheus.InvalidValueError` exception if `value` isn't an integer.<br>
+ 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
@doc """
Decrements the gauge identified by `spec` by `value`.
- Raises `Prometheus.InvalidValueError` exception if `value` isn't an integer.<br>
+ 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
- @doc """
- Increments the gauge identified by `spec` by `value`.
- If `value` happened to be a float number even one time(!) you shouldn't
- use `inc/2` or `dec/2` after dinc.
-
- 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 dinc(spec, value \\ 1) do
- Erlang.metric_call(spec, [value])
- end
-
- @doc """
- Decrements the gauge identified by `spec` by `value`.
- If `value` happened to be a float number even one time(!) you shouldn't
- use `inc/2` or `dec/2` after ddec.
-
- 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 ddec(spec, value \\ 1) do
- Erlang.metric_call(spec, [value])
- end
-
@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
@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))
+
+ 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
- end, env, body)
+ 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)
+
+ 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
- end, env, body)
+ 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
@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
@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
end
diff --git a/lib/prometheus/metric/histogram.ex b/lib/prometheus/metric/histogram.ex
index 9fbb6c4..dc6fbe1 100644
--- a/lib/prometheus/metric/histogram.ex
+++ b/lib/prometheus/metric/histogram.ex
@@ -1,180 +1,171 @@
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
@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
@doc """
Observes the given amount.
Raises `Prometheus.InvalidValueError` exception if `amount` isn't
- a positive integer.<br>
+ 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
- @doc """
- Observes the given amount.
- If `amount` happened to be a float number even one time(!) you shouldn't
- use `observe/2` after dobserve.
-
- Raises `Prometheus.InvalidValueError` exception if `amount` isn't
- a positive integer.<br>
- Raises `Prometheus.UnknownMetricError` exception if a histogram for `spec`
- can't be found.<br>
- Raises `Prometheus.InvalidMetricArityError` exception if labels count mismatch.
- """
- defmacro dobserve(spec, amount \\ 1) do
- Erlang.metric_call(spec, [amount])
- end
-
@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)
+
+ 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
- end, env, body)
+ 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
@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
@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
end
diff --git a/lib/prometheus/metric/summary.ex b/lib/prometheus/metric/summary.ex
index 87957c0..0aa082a 100644
--- a/lib/prometheus/metric/summary.ex
+++ b/lib/prometheus/metric/summary.ex
@@ -1,162 +1,154 @@
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
@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
@doc """
Observes the given amount.
- Raises `Prometheus.InvalidValueError` exception if `amount` isn't an integer.<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
-
- @doc """
- Observes the given amount.
- If `amount` happened to be a float number even one time(!) you shouldn't use `observe/2`
- after dobserve.
-
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 dobserve(spec, amount \\ 1) do
+ defmacro observe(spec, amount \\ 1) do
Erlang.metric_call(spec, [amount])
end
@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)
+
+ 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
- end, env, body)
+ 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
@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
@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
end
diff --git a/lib/prometheus/model.ex b/lib/prometheus/model.ex
index 75637ea..cf6e3e0 100644
--- a/lib/prometheus/model.ex
+++ b/lib/prometheus/model.ex
@@ -1,151 +1,150 @@
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
@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
@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
@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
@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
@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
@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
@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
@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
@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
@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
-
end
diff --git a/lib/prometheus/registry.ex b/lib/prometheus/registry.ex
index 4f1dadb..b81a1a6 100644
--- a/lib/prometheus/registry.ex
+++ b/lib/prometheus/registry.ex
@@ -1,74 +1,73 @@
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
@doc """
Calls `callback` for each collector with two arguments: `registry` and `collector`.
"""
defmacro collect(callback, registry \\ :default) do
Erlang.call([registry, callback])
end
@doc """
Returns collectors registered in `registry`.
"""
defmacro collectors(registry \\ :default) do
Erlang.call([registry])
end
@doc """
Registers a collector.
"""
defmacro register_collector(registry \\ :default, collector) do
Erlang.call([registry, collector])
end
@doc """
Registers collectors list.
"""
defmacro register_collectors(registry \\ :default, collectors) do
Erlang.call([registry, collectors])
end
@doc """
Unregisters a collector.
"""
defmacro deregister_collector(registry \\ :default, collector) do
Erlang.call([registry, collector])
end
@doc """
Unregisters all collectors.
"""
defmacro clear(registry \\ :default) do
Erlang.call([registry])
end
@doc """
Checks whether `collector` is registered.
"""
defmacro collector_registered?(registry \\ :default, collector) do
Erlang.call(:collector_registeredp, [registry, collector])
end
-
end
diff --git a/mix.exs b/mix.exs
index 4e99166..1d9e12d 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,58 +1,72 @@
defmodule PrometheusEx.Mixfile do
use Mix.Project
@version "2.0.0"
def project do
- [app: :prometheus_ex,
- version: @version,
- elixir: "~> 1.3",
- build_embedded: Mix.env == :prod,
- start_permanent: Mix.env == :prod,
- description: description(),
- package: package(),
- name: "Prometheus.ex",
- deps: deps(),
- test_coverage: [tool: ExCoveralls],
- preferred_cli_env: ["coveralls": :test, "coveralls.html": :test],
- docs: [main: Prometheus,
- source_ref: "v#{@version}",
- source_url: "https://github.com/deadtrickster/prometheus.ex",
- extras: ["pages/Mnesia Collector.md",
- "pages/VM Memory Collector.md",
- "pages/VM Statistics Collector.md",
- "pages/VM System Info Collector.md",
- "pages/Time.md"]]]
+ [
+ app: :prometheus_ex,
+ version: @version,
+ elixir: "~> 1.6",
+ build_embedded: Mix.env() == :prod,
+ start_permanent: Mix.env() == :prod,
+ description: description(),
+ package: package(),
+ name: "Prometheus.ex",
+ deps: deps(),
+ test_coverage: [tool: ExCoveralls],
+ preferred_cli_env: [coveralls: :test, "coveralls.html": :test],
+ docs: [
+ main: Prometheus,
+ source_ref: "v#{@version}",
+ source_url: "https://github.com/deadtrickster/prometheus.ex",
+ extras: [
+ "pages/Mnesia Collector.md",
+ "pages/VM Memory Collector.md",
+ "pages/VM Statistics Collector.md",
+ "pages/VM System Info Collector.md",
+ "pages/Time.md"
+ ]
+ ]
+ ]
end
def application do
- [applications: [:logger,
- :prometheus]]
+ [applications: [:logger, :prometheus]]
end
defp description do
"""
Elixir-friendly Prometheus monitoring system client.
"""
end
defp package do
- [maintainers: ["Ilya Khaprov"],
- licenses: ["MIT"],
- links: %{"GitHub" => "https://github.com/deadtrickster/prometheus.ex",
- "Prometheus.erl" => "https://hex.pm/packages/prometheus",
- "Inets HTTPD Exporter" => "https://hex.pm/packages/prometheus_httpd",
- "Ecto Instrumenter" => "https://hex.pm/packages/prometheus_ecto",
- "Phoenix Instrumenter" => "https://hex.pm/packages/prometheus_phoenix",
- "Plugs Instrumenter/Exporter" => "https://hex.pm/packages/prometheus_plugs",
- "Process info Collector" => "https://hex.pm/packages/prometheus_process_collector"}]
+ [
+ maintainers: ["Ilya Khaprov"],
+ licenses: ["MIT"],
+ links: %{
+ "GitHub" => "https://github.com/deadtrickster/prometheus.ex",
+ "Prometheus.erl" => "https://hex.pm/packages/prometheus",
+ "Inets HTTPD Exporter" => "https://hex.pm/packages/prometheus_httpd",
+ "Ecto Instrumenter" => "https://hex.pm/packages/prometheus_ecto",
+ "Phoenix Instrumenter" => "https://hex.pm/packages/prometheus_phoenix",
+ "Plugs Instrumenter/Exporter" => "https://hex.pm/packages/prometheus_plugs",
+ "Process info Collector" => "https://hex.pm/packages/prometheus_process_collector"
+ }
+ ]
end
defp deps do
- [{:prometheus, "~> 3.4"},
- {:credo, "~> 0.8", only: :test},
- {:excoveralls, "~> 0.7", only: :test},
- {:ex_doc, "~> 0.11", only: :dev},
- {:earmark, ">= 0.0.0", only: :dev}]
+ [
+ {:prometheus, "~> 4.0"},
+
+ ## test
+ {:credo, "~> 0.8", only: [:dev, :test]},
+ {:dialyxir, "~> 0.5", only: [:dev]},
+ {:earmark, "~> 1.2", only: [:dev]},
+ {:ex_doc, "~> 0.18", only: [:dev]},
+ {:excoveralls, "~> 0.8", only: [:test]},
+ ]
end
end
diff --git a/mix.lock b/mix.lock
index 5df2510..3f2e1d6 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,15 +1,18 @@
-%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
- "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], []},
- "credo": {:hex, :credo, "0.8.6", "335f723772d35da499b5ebfdaf6b426bfb73590b6fcbc8908d476b75f8cbca3f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]},
- "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], []},
- "ex_doc": {:hex, :ex_doc, "0.16.2", "3b3e210ebcd85a7c76b4e73f85c5640c011d2a0b2f06dcdf5acdb2ae904e5084", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]},
- "excoveralls": {:hex, :excoveralls, "0.7.2", "f69ede8c122ccd3b60afc775348a53fc8c39fe4278aee2f538f0d81cc5e7ff3a", [: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.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, optional: false]}, {:idna, "5.1.0", [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]}]},
- "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, optional: false]}]},
- "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []},
- "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], []},
- "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], []},
- "prometheus": {:hex, :prometheus, "3.4.0", "91759726f2e384df2ef48daf039d506705a7aa81dcbbb2dbffee1fd0c5431d32", [:mix, :rebar3], []},
- "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []},
- "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], []}}
+%{
+ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
+ "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"},
+ "credo": {:hex, :credo, "0.8.10", "261862bb7363247762e1063713bb85df2bbd84af8d8610d1272cd9c1943bba63", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"},
+ "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"},
+ "earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"},
+ "ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
+ "excoveralls": {:hex, :excoveralls, "0.8.1", "0bbf67f22c7dbf7503981d21a5eef5db8bbc3cb86e70d3798e8c802c74fa5e27", [: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.11.0", "4951ee019df102492dabba66a09e305f61919a8a183a7860236c0fde586134b6", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [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"},
+ "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
+ "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"},
+ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"},
+ "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"},
+ "prometheus": {:hex, :prometheus, "4.1.0", "3bb851df031c204d1c94bf55fff2ecc9ab834f0236e64c080c9d5945b48d428d", [:mix, :rebar3], [], "hexpm"},
+ "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
+ "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
+}
diff --git a/test/buckets_test.exs b/test/buckets_test.exs
index 656bf25..4e0f37a 100644
--- a/test/buckets_test.exs
+++ b/test/buckets_test.exs
@@ -1,34 +1,38 @@
defmodule Prometheus.BucketsTest do
use ExUnit.Case
use Prometheus
doctest Prometheus.Buckets
test "linear buckets generator tests" do
assert_raise Prometheus.InvalidValueError, fn ->
- Prometheus.Buckets.linear(-15, 5, 0)
+ Prometheus.Buckets.new({:linear, -15, 5, 0})
end
- assert [-15, -10, -5, 0, 5, 10] == Prometheus.Buckets.linear(-15, 5, 6)
+ assert [-15, -10, -5, 0, 5, 10, :infinity] ==
+ Prometheus.Buckets.new({:linear, -15, 5, 6})
end
test "exponential buckets generator tests" do
assert_raise Prometheus.InvalidValueError, fn ->
- Prometheus.Buckets.exponential(-15, 5, 0)
+ Prometheus.Buckets.new({:exponential, -15, 5, 0})
end
+
assert_raise Prometheus.InvalidValueError, fn ->
- Prometheus.Buckets.exponential(-15, 5, 2)
+ Prometheus.Buckets.new({:exponential, -15, 5, 2})
end
+
assert_raise Prometheus.InvalidValueError, fn ->
- Prometheus.Buckets.exponential(15, 0.5, 3)
+ Prometheus.Buckets.new({:exponential, 15, 0.5, 3})
end
- assert [100, 120, 144] == Prometheus.Buckets.exponential(100, 1.2, 3)
+ assert [100, 120, 144, :infinity] ==
+ Prometheus.Buckets.new({:exponential, 100, 1.2, 3})
end
test "default buckets test" do
- assert [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10] ==
- Prometheus.Buckets.default
+ assert [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, :infinity] ==
+ Prometheus.Buckets.new(:default)
end
end
diff --git a/test/collector_test.exs b/test/collector_test.exs
index ca440cf..6ce9c10 100644
--- a/test/collector_test.exs
+++ b/test/collector_test.exs
@@ -1,44 +1,47 @@
defmodule Prometheus.CollectorTest do
-
use Prometheus.Case
import ExUnit.CaptureIO
def deregister_cleanup(_), do: :ok
test "Collector tests" do
## test collecting metrics from collector in default registry
- Counter.declare([name: :test_counter,
- help: "qwe_qwe"])
+ Counter.declare(
+ name: :test_counter,
+ help: "qwe_qwe"
+ )
- Counter.inc([name: :test_counter])
+ Counter.inc(name: :test_counter)
assert capture_io(fn ->
- Prometheus.Collector.collect_mf(:prometheus_counter, fn(mf) ->
- :io.format("~p", [mf])
- end)
- end) ==
-"{'MetricFamily',<<\"test_counter\">>,\"qwe_qwe\",'COUNTER',
+ Prometheus.Collector.collect_mf(:prometheus_counter, fn mf ->
+ :io.format("~p", [mf])
+ end)
+ end) == "{'MetricFamily',<<\"test_counter\">>,\"qwe_qwe\",'COUNTER',
[{'Metric',[],undefined,
{'Counter',1},
undefined,undefined,undefined,undefined}]}"
## test collecting metrics from collector in custom registry
- Counter.declare([name: :test_counter_qwe,
- help: "qwe_qwe",
- registry: :qwe])
+ Counter.declare(
+ name: :test_counter_qwe,
+ help: "qwe_qwe",
+ registry: :qwe
+ )
- Counter.inc([name: :test_counter_qwe,
- registry: :qwe])
+ Counter.inc(
+ name: :test_counter_qwe,
+ registry: :qwe
+ )
assert capture_io(fn ->
- Prometheus.Collector.collect_mf(:qwe, :prometheus_counter, fn(mf) ->
- :io.format("~p", [mf])
- end)
- end) ==
-"{'MetricFamily',<<\"test_counter_qwe\">>,\"qwe_qwe\",'COUNTER',
+ Prometheus.Collector.collect_mf(:qwe, :prometheus_counter, fn mf ->
+ :io.format("~p", [mf])
+ end)
+ end) == "{'MetricFamily',<<\"test_counter_qwe\">>,\"qwe_qwe\",'COUNTER',
[{'Metric',[],undefined,
{'Counter',1},
undefined,undefined,undefined,undefined}]}"
end
end
diff --git a/test/contrib/http_test.exs b/test/contrib/http_test.exs
index fdcb7b0..3b34371 100644
--- a/test/contrib/http_test.exs
+++ b/test/contrib/http_test.exs
@@ -1,24 +1,41 @@
defmodule Prometheus.Contrib.HTTPTest do
use ExUnit.Case
## alias Prometheus.Error %% FIXME: status_class should throw invalid_value.
use Prometheus
doctest Prometheus.Contrib.HTTP
test "microseconds_duration_buckets" do
- assert [10, 25, 50, 100, 250, 500, 1_000, 2_500, 5_000, 10_000, 25_000, 50_000,
- 100_000, 250_000, 500_000, 1_000_000, 2_500_000, 5_000_000, 10_000_000] ==
- Prometheus.Contrib.HTTP.microseconds_duration_buckets
+ assert [
+ 10,
+ 25,
+ 50,
+ 100,
+ 250,
+ 500,
+ 1_000,
+ 2_500,
+ 5_000,
+ 10_000,
+ 25_000,
+ 50_000,
+ 100_000,
+ 250_000,
+ 500_000,
+ 1_000_000,
+ 2_500_000,
+ 5_000_000,
+ 10_000_000
+ ] == Prometheus.Contrib.HTTP.microseconds_duration_buckets()
end
test "status_class" do
assert 'unknown' == Prometheus.Contrib.HTTP.status_class(50)
assert 'informational' == Prometheus.Contrib.HTTP.status_class(150)
assert 'success' == Prometheus.Contrib.HTTP.status_class(250)
assert 'redirection' == Prometheus.Contrib.HTTP.status_class(350)
assert 'client-error' == Prometheus.Contrib.HTTP.status_class(450)
assert 'server-error' == Prometheus.Contrib.HTTP.status_class(550)
assert 'unknown' == Prometheus.Contrib.HTTP.status_class(650)
end
-
end
diff --git a/test/contrib/mnesia_test.exs b/test/contrib/mnesia_test.exs
index 4ba8123..374fd51 100644
--- a/test/contrib/mnesia_test.exs
+++ b/test/contrib/mnesia_test.exs
@@ -1,34 +1,33 @@
defmodule Prometheus.Contrib.MnesiaTest do
use ExUnit.Case
use Prometheus
test "table disk size" do
{:ok, root} = :file.get_cwd()
mnesia_dir = root ++ '/test/mnesia'
set_custom_mnesia_dir(mnesia_dir)
assert mnesia_dir == :mnesia.system_info(:directory)
assert 3 = Prometheus.Contrib.Mnesia.table_disk_size(mnesia_dir, :table)
assert 21 = Prometheus.Contrib.Mnesia.table_disk_size(:my_table)
end
test "tm info test" do
try do
:mnesia.start()
assert {_, _} = Prometheus.Contrib.Mnesia.tm_info()
after
:mnesia.stop()
end
end
defp set_custom_mnesia_dir(dir) do
:ets.lookup_element(:mnesia_gvar, :dir, 2)
:ets.update_element(:mnesia_gvar, :dir, dir)
rescue
ArgumentError ->
:application.set_env(:mnesia, :dir, dir)
end
-
end
diff --git a/test/error_test.exs b/test/error_test.exs
index 32951e5..e3a7d84 100644
--- a/test/error_test.exs
+++ b/test/error_test.exs
@@ -1,21 +1,18 @@
defmodule Prometheus.ErrorTest do
-
use Prometheus.Case
require Prometheus.Error
def erlang_error do
raise ErlangError
end
test "properly proxies unknown exceptions" do
- assert_raise ArgumentError,
- fn ->
- Prometheus.Error.with_prometheus_error :ets.tab2list(:qweqweqwe)
+ assert_raise ArgumentError, fn ->
+ Prometheus.Error.with_prometheus_error(:ets.tab2list(:qweqweqwe))
end
- assert_raise ErlangError,
- fn ->
- Prometheus.Error.with_prometheus_error erlang_error()
+ assert_raise ErlangError, fn ->
+ Prometheus.Error.with_prometheus_error(erlang_error())
end
end
end
diff --git a/test/format/protobuf_test.exs b/test/format/protobuf_test.exs
index 32b6928..2c678e1 100644
--- a/test/format/protobuf_test.exs
+++ b/test/format/protobuf_test.exs
@@ -1,126 +1,149 @@
# credo:disable-for-this-file Credo.Check.Readability.SpaceAfterCommas
defmodule Prometheus.Format.ProtobufTest do
use Prometheus.Case
require Prometheus.Format.Protobuf
test "content_type" do
assert "application/vnd.google.protobuf; " <>
- "proto=io.prometheus.client.MetricFamily; " <>
- "encoding=delimited" == Prometheus.Format.Protobuf.content_type
+ "proto=io.prometheus.client.MetricFamily; " <> "encoding=delimited" ==
+ Prometheus.Format.Protobuf.content_type()
end
test "gauge" do
- Gauge.new([name: :pool_size, help: "MongoDB Connections pool size"])
+ Gauge.new(name: :pool_size, help: "MongoDB Connections pool size")
Gauge.set([name: :pool_size], 365)
- assert <<57,10,9,112,111,111,108,95,115,105,122,101,18,29,77,111,
- 110,103,111,68,66,32,67,111,110,110,101,99,116,105,111,
- 110,115,32,112,111,111,108,32,115,105,122,101,24,1,34,
- 11,18,9,9,0,0,0,0,0,208,118,64>> == Prometheus.Format.Protobuf.format()
+
+ assert <<57, 10, 9, 112, 111, 111, 108, 95, 115, 105, 122, 101, 18, 29, 77, 111, 110,
+ 103, 111, 68, 66, 32, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 115,
+ 32, 112, 111, 111, 108, 32, 115, 105, 122, 101, 24, 1, 34, 11, 18, 9, 9, 0,
+ 0, 0, 0, 0, 208, 118, 64>> == Prometheus.Format.Protobuf.format()
end
test "counter" do
- Counter.new([name: :http_requests_total, help: "Http request count"])
- Counter.inc([name: :http_requests_total])
- assert <<56,10,19,104,116,116,112,95,114,101,113,117,101,115,116,
- 115,95,116,111,116,97,108,18,18,72,116,116,112,32,114,
- 101,113,117,101,115,116,32,99,111,117,110,116,24,0,34,
- 11,26,9,9,0,0,0,0,0,0,240,63>> == Prometheus.Format.Protobuf.format()
+ Counter.new(name: :http_requests_total, help: "Http request count")
+ Counter.inc(name: :http_requests_total)
+
+ assert <<56, 10, 19, 104, 116, 116, 112, 95, 114, 101, 113, 117, 101, 115, 116, 115,
+ 95, 116, 111, 116, 97, 108, 18, 18, 72, 116, 116, 112, 32, 114, 101, 113,
+ 117, 101, 115, 116, 32, 99, 111, 117, 110, 116, 24, 0, 34, 11, 26, 9, 9, 0,
+ 0, 0, 0, 0, 0, 240, 63>> == Prometheus.Format.Protobuf.format()
end
test "dcounter" do
- Counter.new([name: :dtest, help: "qw\"\\e"])
- Counter.dinc([name: :dtest], 1.5)
- Counter.dinc([name: :dtest], 3.5)
- Counter.dinc([name: :dtest], 1.5)
- :timer.sleep(10)
- assert <<29,10,5,100,116,101,115,116,18,5,113,119,34,92,101,24,0,
- 34,11,26,9,9,0,0,0,0,0,0,26,64>> == Prometheus.Format.Protobuf.format()
+ Counter.new(name: :dtest, help: "qw\"\\e")
+ Counter.inc([name: :dtest], 1.5)
+ Counter.inc([name: :dtest], 3.5)
+ Counter.inc([name: :dtest], 1.5)
+
+ assert <<29, 10, 5, 100, 116, 101, 115, 116, 18, 5, 113, 119, 34, 92, 101, 24, 0, 34,
+ 11, 26, 9, 9, 0, 0, 0, 0, 0, 0, 26,
+ 64>> == Prometheus.Format.Protobuf.format()
end
test "summary" do
- Summary.new([name: :orders_summary, help: "Track orders count/total sum"])
+ Summary.new(name: :orders_summary, help: "Track orders count/total sum")
Summary.observe([name: :orders_summary], 10)
Summary.observe([name: :orders_summary], 15)
- assert <<63,10,14,111,114,100,101,114,115,95,115,117,109,109,97,
- 114,121,18,28,84,114,97,99,107,32,111,114,100,101,114,
- 115,32,99,111,117,110,116,47,116,111,116,97,108,32,115,
- 117,109,24,2,34,13,34,11,8,2,17,0,0,0,0,0,0,57,64>> ==
- Prometheus.Format.Protobuf.format()
+
+ assert <<63, 10, 14, 111, 114, 100, 101, 114, 115, 95, 115, 117, 109, 109, 97, 114,
+ 121, 18, 28, 84, 114, 97, 99, 107, 32, 111, 114, 100, 101, 114, 115, 32, 99,
+ 111, 117, 110, 116, 47, 116, 111, 116, 97, 108, 32, 115, 117, 109, 24, 2, 34,
+ 13, 34, 11, 8, 2, 17, 0, 0, 0, 0, 0, 0, 57,
+ 64>> == Prometheus.Format.Protobuf.format()
end
test "dsummary" do
- Summary.new([name: :dsummary, help: "qwe"])
- Summary.dobserve([name: :dsummary], 1.5)
- Summary.dobserve([name: :dsummary], 2.7)
- :timer.sleep(10)
- assert <<32,10,8,100,115,117,109,109,97,114,121,18,3,113,119,101,
- 24,2,34,13,34,11,8,2,17,205,204,204,204,204,204,16,64>> ==
- Prometheus.Format.Protobuf.format()
+ Summary.new(name: :dsummary, help: "qwe")
+ Summary.observe([name: :dsummary], 1.5)
+ Summary.observe([name: :dsummary], 2.7)
+
+ assert <<32, 10, 8, 100, 115, 117, 109, 109, 97, 114, 121, 18, 3, 113, 119, 101, 24,
+ 2, 34, 13, 34, 11, 8, 2, 17, 205, 204, 204, 204, 204, 204, 16,
+ 64>> == Prometheus.Format.Protobuf.format()
end
test "histogram" do
- Histogram.new([name: :http_request_duration_milliseconds,
- labels: [:method],
- buckets: [100, 300, 500, 750, 1000],
- help: "Http Request execution time",
- duration_unit: false])
+ Histogram.new(
+ name: :http_request_duration_milliseconds,
+ labels: [:method],
+ buckets: [100, 300, 500, 750, 1000],
+ help: "Http Request execution time",
+ duration_unit: false
+ )
+
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 95)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 100)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 102)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 150)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 250)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 75)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 350)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 550)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 950)
- assert <<175,1,10,34,104,116,116,112,95,114,101,113,117,101,115,
- 116,95,100,117,114,97,116,105,111,110,95,109,105,108,
- 108,105,115,101,99,111,110,100,115,18,27,72,116,116,112,
- 32,82,101,113,117,101,115,116,32,101,120,101,99,117,116,
- 105,111,110,32,116,105,109,101,24,4,34,106,10,13,10,6,
- 109,101,116,104,111,100,18,3,103,101,116,58,89,8,9,17,0,
- 0,0,0,0,124,164,64,26,11,8,3,17,0,0,0,0,0,0,89,64,26,11,
- 8,6,17,0,0,0,0,0,192,114,64,26,11,8,7,17,0,0,0,0,0,64,
- 127,64,26,11,8,8,17,0,0,0,0,0,112,135,64,26,11,8,9,17,0,
- 0,0,0,0,64,143,64,26,11,8,9,17,0,0,0,0,0,0,240,127>> ==
- Prometheus.Format.Protobuf.format()
-
+ assert <<175, 1, 10, 34, 104, 116, 116, 112, 95, 114, 101, 113, 117, 101, 115, 116,
+ 95, 100, 117, 114, 97, 116, 105, 111, 110, 95, 109, 105, 108, 108, 105, 115,
+ 101, 99, 111, 110, 100, 115, 18, 27, 72, 116, 116, 112, 32, 82, 101, 113,
+ 117, 101, 115, 116, 32, 101, 120, 101, 99, 117, 116, 105, 111, 110, 32, 116,
+ 105, 109, 101, 24, 4, 34, 106, 10, 13, 10, 6, 109, 101, 116, 104, 111, 100,
+ 18, 3, 103, 101, 116, 58, 89, 8, 9, 17, 0, 0, 0, 0, 0, 124, 164, 64, 26, 11,
+ 8, 3, 17, 0, 0, 0, 0, 0, 0, 89, 64, 26, 11, 8, 6, 17, 0, 0, 0, 0, 0, 192,
+ 114, 64, 26, 11, 8, 7, 17, 0, 0, 0, 0, 0, 64, 127, 64, 26, 11, 8, 8, 17, 0,
+ 0, 0, 0, 0, 112, 135, 64, 26, 11, 8, 9, 17, 0, 0, 0, 0, 0, 64, 143, 64, 26,
+ 11, 8, 9, 17, 0, 0, 0, 0, 0, 0, 240,
+ 127>> == Prometheus.Format.Protobuf.format()
end
test "dhistogram" do
- Histogram.new([name: :http_request_duration_milliseconds,
- labels: [:method],
- buckets: [100, 300, 500, 750, 1000],
- help: "Http Request execution time",
- duration_unit: false])
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 500.2)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 150.4)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 450.5)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 850.3)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 750.9)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 1650.23)
-
- :timer.sleep(10)
-
- assert <<176,1,10,34,104,116,116,112,95,114,101,113,117,101,115,
- 116,95,100,117,114,97,116,105,111,110,95,109,105,108,
- 108,105,115,101,99,111,110,100,115,18,27,72,116,116,112,
- 32,82,101,113,117,101,115,116,32,101,120,101,99,117,116,
- 105,111,110,32,116,105,109,101,24,4,34,107,10,14,10,6,
- 109,101,116,104,111,100,18,4,112,111,115,116,58,89,8,6,
- 17,225,122,20,174,135,0,177,64,26,11,8,0,17,0,0,0,0,0,0,
- 89,64,26,11,8,1,17,0,0,0,0,0,192,114,64,26,11,8,2,17,0,
- 0,0,0,0,64,127,64,26,11,8,3,17,0,0,0,0,0,112,135,64,26,
- 11,8,5,17,0,0,0,0,0,64,143,64,26,11,8,6,17,0,0,0,0,0,0,
- 240,127>> == Prometheus.Format.Protobuf.format()
+ Histogram.new(
+ name: :http_request_duration_milliseconds,
+ labels: [:method],
+ buckets: [100, 300, 500, 750, 1000],
+ help: "Http Request execution time",
+ duration_unit: false
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 500.2
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 150.4
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 450.5
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 850.3
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 750.9
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 1650.23
+ )
+ assert <<176, 1, 10, 34, 104, 116, 116, 112, 95, 114, 101, 113, 117, 101, 115, 116,
+ 95, 100, 117, 114, 97, 116, 105, 111, 110, 95, 109, 105, 108, 108, 105, 115,
+ 101, 99, 111, 110, 100, 115, 18, 27, 72, 116, 116, 112, 32, 82, 101, 113,
+ 117, 101, 115, 116, 32, 101, 120, 101, 99, 117, 116, 105, 111, 110, 32, 116,
+ 105, 109, 101, 24, 4, 34, 107, 10, 14, 10, 6, 109, 101, 116, 104, 111, 100,
+ 18, 4, 112, 111, 115, 116, 58, 89, 8, 6, 17, 225, 122, 20, 174, 135, 0, 177,
+ 64, 26, 11, 8, 0, 17, 0, 0, 0, 0, 0, 0, 89, 64, 26, 11, 8, 1, 17, 0, 0, 0, 0,
+ 0, 192, 114, 64, 26, 11, 8, 2, 17, 0, 0, 0, 0, 0, 64, 127, 64, 26, 11, 8, 3,
+ 17, 0, 0, 0, 0, 0, 112, 135, 64, 26, 11, 8, 5, 17, 0, 0, 0, 0, 0, 64, 143,
+ 64, 26, 11, 8, 6, 17, 0, 0, 0, 0, 0, 0, 240,
+ 127>> == Prometheus.Format.Protobuf.format()
end
end
diff --git a/test/format/text_test.exs b/test/format/text_test.exs
index 823718e..e7118b3 100644
--- a/test/format/text_test.exs
+++ b/test/format/text_test.exs
@@ -1,142 +1,151 @@
defmodule Prometheus.Format.TextTest do
use Prometheus.Case
require Prometheus.Format.Text
test "content_type" do
- assert "text/plain; version=0.0.4" == Prometheus.Format.Text.content_type
+ assert "text/plain; version=0.0.4" == Prometheus.Format.Text.content_type()
end
test "gauge" do
- Gauge.new([name: :pool_size, help: "MongoDB Connections pool size"])
+ Gauge.new(name: :pool_size, help: "MongoDB Connections pool size")
Gauge.set([name: :pool_size], 365)
+
assert ~s"""
- # TYPE pool_size gauge
- # HELP pool_size MongoDB Connections pool size
- pool_size 365
+ # TYPE pool_size gauge
+ # HELP pool_size MongoDB Connections pool size
+ pool_size 365
- """
- == Prometheus.Format.Text.format()
+ """ == Prometheus.Format.Text.format()
end
test "counter" do
- Counter.new([name: :http_requests_total, help: "Http request count"])
- Counter.inc([name: :http_requests_total])
+ Counter.new(name: :http_requests_total, help: "Http request count")
+ Counter.inc(name: :http_requests_total)
+
assert ~s"""
- # TYPE http_requests_total counter
- # HELP http_requests_total Http request count
- http_requests_total 1
+ # TYPE http_requests_total counter
+ # HELP http_requests_total Http request count
+ http_requests_total 1
- """ == Prometheus.Format.Text.format()
+ """ == Prometheus.Format.Text.format()
end
test "dcounter" do
- Counter.new([name: :dtest, help: "qw\"\\e"])
- Counter.dinc([name: :dtest], 1.5)
- Counter.dinc([name: :dtest], 3.5)
- Counter.dinc([name: :dtest], 1.5)
- :timer.sleep(10)
+ Counter.new(name: :dtest, help: "qw\"\\e")
+ Counter.inc([name: :dtest], 1.5)
+ Counter.inc([name: :dtest], 3.5)
+ Counter.inc([name: :dtest], 1.5)
+
assert ~s"""
- # TYPE dtest counter
- # HELP dtest qw\"\\\\e
- dtest 6.5
+ # TYPE dtest counter
+ # HELP dtest qw\"\\\\e
+ dtest 6.5
- """ == Prometheus.Format.Text.format()
+ """ == Prometheus.Format.Text.format()
end
test "summary" do
- Summary.new([name: :orders_summary, help: "Track orders count/total sum"])
+ Summary.new(name: :orders_summary, help: "Track orders count/total sum")
Summary.observe([name: :orders_summary], 10)
Summary.observe([name: :orders_summary], 15)
- assert ~s"""
- # TYPE orders_summary summary
- # HELP orders_summary Track orders count/total sum
- orders_summary_count 2
- orders_summary_sum 25
+ Summary.observe([name: :orders_summary], 1.5)
+ Summary.observe([name: :orders_summary], 2.7)
- """ == Prometheus.Format.Text.format()
- end
-
- test "dsummary" do
- Summary.new([name: :dsummary, help: "qwe"])
- Summary.dobserve([name: :dsummary], 1.5)
- Summary.dobserve([name: :dsummary], 2.7)
- :timer.sleep(10)
assert ~s"""
- # TYPE dsummary summary
- # HELP dsummary qwe
- dsummary_count 2
- dsummary_sum 4.2
+ # TYPE orders_summary summary
+ # HELP orders_summary Track orders count/total sum
+ orders_summary_count 4
+ orders_summary_sum 29.2
- """ == Prometheus.Format.Text.format()
+ """ == Prometheus.Format.Text.format()
end
test "histogram" do
- Histogram.new([name: :http_request_duration_milliseconds,
- labels: [:method],
- buckets: [100, 300, 500, 750, 1000],
- help: "Http Request execution time",
- duration_unit: false])
+ Histogram.new(
+ name: :http_request_duration_milliseconds,
+ labels: [:method],
+ buckets: [100, 300, 500, 750, 1000],
+ help: "Http Request execution time",
+ duration_unit: false
+ )
+
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 95)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 100)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 102)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 150)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 250)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 75)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 350)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 550)
Histogram.observe([name: :http_request_duration_milliseconds, labels: [:get]], 950)
assert ~s"""
- # TYPE http_request_duration_milliseconds histogram
- # HELP http_request_duration_milliseconds Http Request execution time
- http_request_duration_milliseconds_bucket{method="get",le="100"} 3
- http_request_duration_milliseconds_bucket{method="get",le="300"} 6
- http_request_duration_milliseconds_bucket{method="get",le="500"} 7
- http_request_duration_milliseconds_bucket{method="get",le="750"} 8
- http_request_duration_milliseconds_bucket{method="get",le="1000"} 9
- http_request_duration_milliseconds_bucket{method="get",le="+Inf"} 9
- http_request_duration_milliseconds_count{method="get"} 9
- http_request_duration_milliseconds_sum{method="get"} 2622
-
- """ == Prometheus.Format.Text.format()
-
+ # TYPE http_request_duration_milliseconds histogram
+ # HELP http_request_duration_milliseconds Http Request execution time
+ http_request_duration_milliseconds_bucket{method="get",le="100"} 3
+ http_request_duration_milliseconds_bucket{method="get",le="300"} 6
+ http_request_duration_milliseconds_bucket{method="get",le="500"} 7
+ http_request_duration_milliseconds_bucket{method="get",le="750"} 8
+ http_request_duration_milliseconds_bucket{method="get",le="1000"} 9
+ http_request_duration_milliseconds_bucket{method="get",le="+Inf"} 9
+ http_request_duration_milliseconds_count{method="get"} 9
+ http_request_duration_milliseconds_sum{method="get"} 2622
+
+ """ == Prometheus.Format.Text.format()
end
test "dhistogram" do
- Histogram.new([name: :http_request_duration_milliseconds,
- labels: [:method],
- buckets: [100, 300, 500, 750, 1000],
- help: "Http Request execution time",
- duration_unit: false])
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 500.2)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 150.4)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 450.5)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 850.3)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 750.9)
- Histogram.dobserve(
- [name: :http_request_duration_milliseconds, labels: [:post]], 1650.23)
-
- :timer.sleep(10)
+ Histogram.new(
+ name: :http_request_duration_milliseconds,
+ labels: [:method],
+ buckets: [100, 300, 500, 750, 1000],
+ help: "Http Request execution time",
+ duration_unit: false
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 500.2
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 150.4
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 450.5
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 850.3
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 750.9
+ )
+
+ Histogram.observe(
+ [name: :http_request_duration_milliseconds, labels: [:post]],
+ 1650.23
+ )
assert ~s"""
- # TYPE http_request_duration_milliseconds histogram
- # HELP http_request_duration_milliseconds Http Request execution time
- http_request_duration_milliseconds_bucket{method=\"post\",le=\"100\"} 0
- http_request_duration_milliseconds_bucket{method=\"post\",le=\"300\"} 1
- http_request_duration_milliseconds_bucket{method=\"post\",le=\"500\"} 2
- http_request_duration_milliseconds_bucket{method=\"post\",le=\"750\"} 3
- http_request_duration_milliseconds_bucket{method=\"post\",le=\"1000\"} 5
- http_request_duration_milliseconds_bucket{method=\"post\",le=\"+Inf\"} 6
- http_request_duration_milliseconds_count{method=\"post\"} 6
- http_request_duration_milliseconds_sum{method=\"post\"} 4352.53
-
- """ == Prometheus.Format.Text.format()
-
+ # TYPE http_request_duration_milliseconds histogram
+ # HELP http_request_duration_milliseconds Http Request execution time
+ http_request_duration_milliseconds_bucket{method=\"post\",le=\"100\"} 0
+ http_request_duration_milliseconds_bucket{method=\"post\",le=\"300\"} 1
+ http_request_duration_milliseconds_bucket{method=\"post\",le=\"500\"} 2
+ http_request_duration_milliseconds_bucket{method=\"post\",le=\"750\"} 3
+ http_request_duration_milliseconds_bucket{method=\"post\",le=\"1000\"} 5
+ http_request_duration_milliseconds_bucket{method=\"post\",le=\"+Inf\"} 6
+ http_request_duration_milliseconds_count{method=\"post\"} 6
+ http_request_duration_milliseconds_sum{method=\"post\"} 4352.53
+
+ """ == Prometheus.Format.Text.format()
end
end
diff --git a/test/injector_test.exs b/test/injector_test.exs
index c697cdd..ade3193 100644
--- a/test/injector_test.exs
+++ b/test/injector_test.exs
@@ -1,158 +1,160 @@
defmodule Injector do
-
defmacro test(ast) do
- Prometheus.Injector.inject(fn(block) ->
- quote do
- try do
- IO.puts("before block")
- unquote(block)
- after
- IO.puts("after block")
+ Prometheus.Injector.inject(
+ fn block ->
+ quote do
+ try do
+ IO.puts("before block")
+ unquote(block)
+ after
+ IO.puts("after block")
+ end
end
- end
- end, __CALLER__, ast)
+ end,
+ __CALLER__,
+ ast
+ )
end
-
end
defmodule Prometheus.InjectorTest do
use Prometheus.Case
require Injector
Injector.test do
def fun1() do
IO.puts("fun1")
end
def fun2() do
IO.puts("fun2")
end
Injector.test do
def fun3() do
IO.puts("fun3")
rescue
e in RuntimeError ->
IO.puts(e)
end
end
end
def do_dangerous_work(x) do
Injector.test do
IO.puts("Doing dangerous work #{x}")
rescue
_ -> IO.puts("Died")
after
IO.puts("Done anyway")
end
end
test "fn" do
assert capture_io(fn ->
- Injector.test(fn () -> IO.puts("qwe") end)
- end) ==
- "before block\nqwe\nafter block\n"
+ Injector.test(fn -> IO.puts("qwe") end)
+ end) == "before block\nqwe\nafter block\n"
end
test "blocks" do
- assert capture_io(fn () ->
- Injector.test IO.puts("qwe")
- end) == "before block\nqwe\nafter block\n"
-
- assert capture_io(fn () ->
- Injector.test do: IO.puts("qwe")
- end) == "before block\nqwe\nafter block\n"
-
- assert capture_io(fn () ->
- Injector.test do
- IO.puts("qwe")
- IO.puts("qwa")
- end
- end) == "before block\nqwe\nqwa\nafter block\n"
+ assert capture_io(fn ->
+ Injector.test(IO.puts("qwe"))
+ end) == "before block\nqwe\nafter block\n"
+
+ assert capture_io(fn ->
+ Injector.test(do: IO.puts("qwe"))
+ end) == "before block\nqwe\nafter block\n"
+
+ assert capture_io(fn ->
+ Injector.test do
+ IO.puts("qwe")
+ IO.puts("qwa")
+ end
+ end) == "before block\nqwe\nqwa\nafter block\n"
end
test "implicit try" do
- assert capture_io(fn () ->
- do_dangerous_work(5)
- end) == "before block\nDoing dangerous work 5\nDone anyway\nafter block\n"
+ assert capture_io(fn ->
+ do_dangerous_work(5)
+ end) == "before block\nDoing dangerous work 5\nDone anyway\nafter block\n"
- assert capture_io(fn () ->
- do_dangerous_work({})
- end) == "before block\nDied\nDone anyway\nafter block\n"
+ assert capture_io(fn ->
+ do_dangerous_work({})
+ end) == "before block\nDied\nDone anyway\nafter block\n"
end
test "defs" do
- assert capture_io(fn () ->
- fun1()
- end) == "before block\nfun1\nafter block\n"
+ assert capture_io(fn ->
+ fun1()
+ end) == "before block\nfun1\nafter block\n"
- assert capture_io(fn () ->
- fun2()
- end) == "before block\nfun2\nafter block\n"
+ assert capture_io(fn ->
+ fun2()
+ end) == "before block\nfun2\nafter block\n"
- assert capture_io(fn () ->
- fun3()
- end) == "before block\nbefore block\nfun3\nafter block\nafter block\n"
+ assert capture_io(fn ->
+ fun3()
+ end) == "before block\nbefore block\nfun3\nafter block\nafter block\n"
end
defmodule QweInjector do
defmacro inject_(body) do
- Prometheus.Injector.inject_(body, fn(b) ->
+ Prometheus.Injector.inject_(body, fn b ->
quote do
IO.puts("qwe")
+
try do
unquote(b)
after
IO.puts("after_qwe")
end
end
end)
end
+
defmacro inject1(body) do
body
end
end
defmodule UsefulModule do
require QweInjector
def do_work(x) do
QweInjector.inject_ do
- IO.puts("Doing work #{inspect x}")
+ IO.puts("Doing work #{inspect(x)}")
end
end
def do_dangerous_work(x) do
QweInjector.inject_ do
IO.puts("Doing dangerous work #{x}")
rescue
_ -> IO.puts("Died")
after
IO.puts("Done anyway")
end
end
QweInjector.inject_ do
def mildly_interesting(what) do
IO.puts("#{what} is mildly interesting")
end
def wtf(what) do
IO.puts("#{what} is wtf")
rescue
- _ -> IO.puts("Oh my, #{inspect what} is real wtf")
+ _ -> IO.puts("Oh my, #{inspect(what)} is real wtf")
else
_ -> IO.puts("Saw wtf and still stronk")
end
end
end
test "UsefulModule" do
- assert capture_io(fn () ->
- UsefulModule.wtf({})
- end) ==
- "qwe\nOh my, {} is real wtf\nafter_qwe\n"
+ assert capture_io(fn ->
+ UsefulModule.wtf({})
+ end) == "qwe\nOh my, {} is real wtf\nafter_qwe\n"
end
end
diff --git a/test/metric/boolean_test.exs b/test/metric/boolean_test.exs
index 94a5ba9..20d5943 100644
--- a/test/metric/boolean_test.exs
+++ b/test/metric/boolean_test.exs
@@ -1,210 +1,193 @@
defmodule Prometheus.BooleanTest do
use Prometheus.Case
test "registration" do
- spec = [name: :name,
- help: "",
- registry: :qwe]
+ spec = [name: :name, help: "", registry: :qwe]
assert true == Boolean.declare(spec)
assert false == Boolean.declare(spec)
- assert_raise Prometheus.MFAlreadyExistsError,
- "Metric qwe:name already exists.",
- fn ->
+
+ assert_raise Prometheus.MFAlreadyExistsError, "Metric qwe:name already exists.", fn ->
Boolean.new(spec)
end
end
test "spec errors" do
assert_raise Prometheus.MissingMetricSpecKeyError,
- "Required key name is missing from metric spec.",
- fn ->
- Boolean.new([help: ""])
- end
- assert_raise Prometheus.InvalidMetricNameError,
- "Invalid metric name: 12.",
- fn ->
- Boolean.new([name: 12, help: ""])
+ "Required key name is missing from metric spec.",
+ fn ->
+ Boolean.new(help: "")
+ end
+
+ assert_raise Prometheus.InvalidMetricNameError, "Invalid metric name: 12.", fn ->
+ Boolean.new(name: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricLabelsError,
- "Invalid metric labels: 12.",
- fn ->
- Boolean.new([name: "qwe", labels: 12, help: ""])
+
+ assert_raise Prometheus.InvalidMetricLabelsError, "Invalid metric labels: 12.", fn ->
+ Boolean.new(name: "qwe", labels: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricHelpError,
- "Invalid metric help: 12.",
- fn ->
- Boolean.new([name: "qwe", help: 12])
+
+ assert_raise Prometheus.InvalidMetricHelpError, "Invalid metric help: 12.", fn ->
+ Boolean.new(name: "qwe", help: 12)
end
end
test "boolean specific errors" do
- spec = [name: :fuse_state,
- labels: [:qwe],
- help: ""]
+ spec = [name: :fuse_state, labels: [:qwe], help: ""]
Boolean.declare(spec)
## set
assert_raise Prometheus.InvalidValueError,
- "Invalid value: %{} (value is not boolean).",
- fn ->
- Boolean.set(spec, %{})
- end
+ "Invalid value: %{} (value is not boolean).",
+ fn ->
+ Boolean.set(spec, %{})
+ end
## toggle
Boolean.set(spec, :undefined)
+
assert_raise Prometheus.InvalidValueError,
- "Invalid value: :undefined (can't toggle undefined boolean).",
- fn ->
- Boolean.toggle(spec)
- end
+ "Invalid value: :undefined (can't toggle undefined boolean).",
+ fn ->
+ Boolean.toggle(spec)
+ end
end
test "mf/arity errors" do
- spec = [name: :metric_with_label,
- labels: [:label],
- help: ""]
+ spec = [name: :metric_with_label, labels: [:label], help: ""]
Boolean.declare(spec)
## set
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Boolean.set(:unknown_metric, true)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Boolean.set(:unknown_metric, true)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Boolean.set([name: :metric_with_label, labels: [:l1, :l2]], true)
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Boolean.set([name: :metric_with_label, labels: [:l1, :l2]], true)
+ end
## toggle
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Boolean.toggle(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Boolean.toggle(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Boolean.toggle([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Boolean.toggle(name: :metric_with_label, labels: [:l1, :l2])
+ end
## remove
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Boolean.remove(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Boolean.remove(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Boolean.remove([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Boolean.remove(name: :metric_with_label, labels: [:l1, :l2])
+ end
## reset
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Boolean.reset(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Boolean.reset(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Boolean.reset([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Boolean.reset(name: :metric_with_label, labels: [:l1, :l2])
+ end
## value
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Boolean.value(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Boolean.value(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Boolean.value([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Boolean.value(name: :metric_with_label, labels: [:l1, :l2])
+ end
end
test "set" do
- spec = [name: :fuse_state,
- labels: [:name],
- help: ""]
+ spec = [name: :fuse_state, labels: [:name], help: ""]
Boolean.new(spec)
Boolean.set(spec, 110)
assert true == Boolean.value(spec)
Boolean.set(spec, 0)
assert false == Boolean.value(spec)
Boolean.set(spec, true)
assert true == Boolean.value(spec)
Boolean.set(spec, false)
assert false == Boolean.value(spec)
Boolean.set(spec, [1])
assert true == Boolean.value(spec)
Boolean.set(spec, [])
assert false == Boolean.value(spec)
Boolean.reset(spec)
assert false == Boolean.value(spec)
end
test "toggle" do
- spec = [name: :fuse_state,
- labels: [:name],
- help: ""]
+ spec = [name: :fuse_state, labels: [:name], help: ""]
Boolean.new(spec)
Boolean.set(spec, 110)
assert true == Boolean.value(spec)
Boolean.toggle(spec)
assert false == Boolean.value(spec)
Boolean.toggle(spec)
assert true == Boolean.value(spec)
end
test "remove" do
- fuse_state = [name: :fuse_state,
- labels: [:name],
- help: ""]
+ fuse_state = [name: :fuse_state, labels: [:name], help: ""]
Boolean.new(fuse_state)
- simple_boolean = [name: :simple_boolean,
- labels: [],
- help: ""]
+ simple_boolean = [name: :simple_boolean, labels: [], help: ""]
Boolean.new(simple_boolean)
Boolean.set(fuse_state, true)
Boolean.set(simple_boolean, true)
assert true == Boolean.value(fuse_state)
assert true == Boolean.value(simple_boolean)
assert true == Boolean.remove(fuse_state)
assert true == Boolean.remove(simple_boolean)
assert :undefined == Boolean.value(fuse_state)
assert :undefined == Boolean.value(simple_boolean)
assert false == Boolean.remove(fuse_state)
assert false == Boolean.remove(simple_boolean)
end
test "default value" do
- fuse_state = [name: :fuse_state,
- labels: [:name],
- help: ""]
+ fuse_state = [name: :fuse_state, labels: [:name], help: ""]
Boolean.new(fuse_state)
- simple_boolean = [name: :simple_boolean,
- labels: [],
- help: ""]
+ simple_boolean = [name: :simple_boolean, labels: [], help: ""]
Boolean.new(simple_boolean)
assert :undefined == Boolean.value(fuse_state)
assert :undefined == Boolean.value(simple_boolean)
end
-
end
diff --git a/test/metric/counter_test.exs b/test/metric/counter_test.exs
index 3b96625..d1f66bd 100644
--- a/test/metric/counter_test.exs
+++ b/test/metric/counter_test.exs
@@ -1,312 +1,261 @@
defmodule Prometheus.CounterTest do
use Prometheus.Case
test "registration" do
- spec = [name: :name,
- help: "",
- registry: :qwe]
+ spec = [name: :name, help: "", registry: :qwe]
assert true == Counter.declare(spec)
assert false == Counter.declare(spec)
- assert_raise Prometheus.MFAlreadyExistsError,
- "Metric qwe:name already exists.",
- fn ->
+
+ assert_raise Prometheus.MFAlreadyExistsError, "Metric qwe:name already exists.", fn ->
Counter.new(spec)
end
end
test "spec errors" do
assert_raise Prometheus.MissingMetricSpecKeyError,
- "Required key name is missing from metric spec.",
- fn ->
- Counter.new([help: ""])
- end
- assert_raise Prometheus.InvalidMetricNameError,
- "Invalid metric name: 12.",
- fn ->
- Counter.new([name: 12, help: ""])
+ "Required key name is missing from metric spec.",
+ fn ->
+ Counter.new(help: "")
+ end
+
+ assert_raise Prometheus.InvalidMetricNameError, "Invalid metric name: 12.", fn ->
+ Counter.new(name: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricLabelsError,
- "Invalid metric labels: 12.",
- fn ->
- Counter.new([name: "qwe", labels: 12, help: ""])
+
+ assert_raise Prometheus.InvalidMetricLabelsError, "Invalid metric labels: 12.", fn ->
+ Counter.new(name: "qwe", labels: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricHelpError,
- "Invalid metric help: 12.",
- fn ->
- Counter.new([name: "qwe", help: 12])
+
+ assert_raise Prometheus.InvalidMetricHelpError, "Invalid metric help: 12.", fn ->
+ Counter.new(name: "qwe", help: 12)
end
end
test "counter specific errors" do
- spec = [name: :http_requests_total,
- help: ""]
+ spec = [name: :http_requests_total, help: ""]
## inc
assert_raise Prometheus.InvalidValueError,
- "Invalid value: -1 (inc accepts only non-negative integers).",
- fn ->
- Counter.inc(spec, -1)
- end
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: 1.5 (inc accepts only non-negative integers).",
- fn ->
- Counter.inc(spec, 1.5)
- end
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (inc accepts only non-negative integers).",
- fn ->
- Counter.inc(spec, "qwe")
- end
+ "Invalid value: -1 (inc accepts only non-negative numbers).",
+ fn ->
+ Counter.inc(spec, -1)
+ end
- ## dinc
assert_raise Prometheus.InvalidValueError,
- "Invalid value: -1 (dinc accepts only non-negative numbers).",
- fn ->
- Counter.dinc(spec, -1)
- end
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (dinc accepts only non-negative numbers).",
- fn ->
- Counter.dinc(spec, "qwe")
- end
+ "Invalid value: \"qwe\" (inc accepts only non-negative numbers).",
+ fn ->
+ Counter.inc(spec, "qwe")
+ end
end
test "mf/arity errors" do
- spec = [name: :metric_with_label,
- labels: [:label],
- help: ""]
+ spec = [name: :metric_with_label, labels: [:label], help: ""]
Counter.declare(spec)
## inc
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Counter.inc(:unknown_metric)
- end
- assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Counter.inc([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Counter.inc(:unknown_metric)
+ end
- ## dinc
- assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Counter.dinc(:unknown_metric)
- end
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Counter.dinc([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Counter.inc(name: :metric_with_label, labels: [:l1, :l2])
+ end
## remove
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Counter.remove(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Counter.remove(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Counter.remove([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Counter.remove(name: :metric_with_label, labels: [:l1, :l2])
+ end
## reset
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Counter.reset(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Counter.reset(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Counter.reset([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Counter.reset(name: :metric_with_label, labels: [:l1, :l2])
+ end
## value
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Counter.value(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Counter.value(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Counter.value([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Counter.value(name: :metric_with_label, labels: [:l1, :l2])
+ end
end
test "inc" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Counter.new(spec)
Counter.inc(spec)
Counter.inc(spec, 3)
- assert 4 == Counter.value(spec)
-
- Counter.reset(spec)
-
- assert 0 == Counter.value(spec)
- end
-
- test "dinc" do
- spec = [name: :http_requests_total,
- help: ""]
- Counter.new(spec)
-
- Counter.dinc(spec)
- Counter.dinc(spec, 3.5)
+ Counter.inc(spec)
+ Counter.inc(spec, 3.5)
- ## dinc is async. let's make sure gen_server processed our request
- Process.sleep(10)
- assert 4.5 == Counter.value(spec)
+ assert 8.5 == Counter.value(spec)
Counter.reset(spec)
assert 0 == Counter.value(spec)
end
test "remove" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- wl_spec = [name: :simple_counter,
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
+ wl_spec = [name: :simple_counter, help: ""]
Counter.new(spec)
Counter.new(wl_spec)
Counter.inc(spec)
Counter.inc(wl_spec)
assert 1 == Counter.value(spec)
assert 1 == Counter.value(wl_spec)
assert true == Counter.remove(spec)
assert true == Counter.remove(wl_spec)
assert :undefined == Counter.value(spec)
assert :undefined == Counter.value(wl_spec)
assert false == Counter.remove(spec)
assert false == Counter.remove(wl_spec)
end
test "default value" do
- lspec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ lspec = [name: :http_requests_total, labels: [:method], help: ""]
Counter.new(lspec)
assert :undefined == Counter.value(lspec)
- spec = [name: :something_total,
- labels: [],
- help: ""]
+ spec = [name: :something_total, labels: [], help: ""]
Counter.new(spec)
assert 0 == Counter.value(spec)
end
defmodule CounterInjectorsTest do
-
use Prometheus.Metric
@counter name: :calls_total, help: ""
@counter name: :sometimes_total, help: ""
@counter name: :exceptions_total, help: ""
@counter name: :no_exceptions_total, help: ""
Counter.count name: :calls_total do
def decorated_fun() do
IO.puts("I'm decorated fun")
end
def decorated_fun1() do
IO.puts("I'm decorated fun1")
IO.puts("I'm decorated fun1")
end
end
def sometimes_count(arg) do
if arg do
- Counter.count [name: :sometimes_total], do: IO.puts "Called indeed!"
+ Counter.count([name: :sometimes_total], do: IO.puts("Called indeed!"))
else
IO.puts("Not this time")
end
end
- Counter.count_no_exceptions [name: :no_exceptions_total] do
+ Counter.count_no_exceptions name: :no_exceptions_total do
Counter.count_exceptions [name: :exceptions_total], ArithmeticError do
def sometimes_raise(arg) do
5 / arg
end
end
def sometimes_raise1(arg) when is_list(arg) do
5 / arg
end
end
- def qwe () do
- Counter.count_no_exceptions [name: :no_exceptions_total], fn () ->
- IO.puts 1
- IO.puts 2
- end
+ def qwe() do
+ Counter.count_no_exceptions([name: :no_exceptions_total], fn ->
+ IO.puts(1)
+ IO.puts(2)
+ end)
end
- Counter.count_exceptions [name: :exceptions_total] do
+ Counter.count_exceptions name: :exceptions_total do
def sometimes_raise_any(arg) do
5 / arg
end
end
end
test "decorators test" do
-
CounterInjectorsTest.__declare_prometheus_metrics__()
- assert 0 == Counter.value name: :calls_total
+ assert 0 == Counter.value(name: :calls_total)
+
assert capture_io(fn -> CounterInjectorsTest.decorated_fun() end) ==
- "I'm decorated fun\n"
- assert 1 == Counter.value name: :calls_total
+ "I'm decorated fun\n"
+
+ assert 1 == Counter.value(name: :calls_total)
+
assert capture_io(fn -> CounterInjectorsTest.decorated_fun1() end) ==
- "I'm decorated fun1\nI'm decorated fun1\n"
- assert 2 == Counter.value name: :calls_total
+ "I'm decorated fun1\nI'm decorated fun1\n"
+
+ assert 2 == Counter.value(name: :calls_total)
+
+ assert 0 == Counter.value(name: :sometimes_total)
- assert 0 == Counter.value name: :sometimes_total
assert capture_io(fn -> CounterInjectorsTest.sometimes_count(true) end) ==
- "Called indeed!\n"
+ "Called indeed!\n"
+
assert capture_io(fn -> CounterInjectorsTest.sometimes_count(false) end) ==
- "Not this time\n"
- assert 1 == Counter.value name: :sometimes_total
+ "Not this time\n"
+
+ assert 1 == Counter.value(name: :sometimes_total)
- assert 0 == Counter.value name: :exceptions_total
- assert 0 == Counter.value name: :no_exceptions_total
+ assert 0 == Counter.value(name: :exceptions_total)
+ assert 0 == Counter.value(name: :no_exceptions_total)
assert 1 == CounterInjectorsTest.sometimes_raise(5)
- assert 0 == Counter.value name: :exceptions_total
- assert 1 == Counter.value name: :no_exceptions_total
- assert_raise ArithmeticError,
- fn ->
+ assert 0 == Counter.value(name: :exceptions_total)
+ assert 1 == Counter.value(name: :no_exceptions_total)
+
+ assert_raise ArithmeticError, fn ->
CounterInjectorsTest.sometimes_raise(0)
end
- assert 1 == Counter.value name: :exceptions_total
- assert 1 == Counter.value name: :no_exceptions_total
- assert 1 == Counter.value name: :exceptions_total
+ assert 1 == Counter.value(name: :exceptions_total)
+ assert 1 == Counter.value(name: :no_exceptions_total)
+
+ assert 1 == Counter.value(name: :exceptions_total)
assert 1 == CounterInjectorsTest.sometimes_raise(5)
- assert 1 == Counter.value name: :exceptions_total
- assert_raise ArithmeticError,
- fn ->
+ assert 1 == Counter.value(name: :exceptions_total)
+
+ assert_raise ArithmeticError, fn ->
CounterInjectorsTest.sometimes_raise(0)
end
- assert 2 == Counter.value name: :exceptions_total
+ assert 2 == Counter.value(name: :exceptions_total)
end
-
end
diff --git a/test/metric/gauge_test.exs b/test/metric/gauge_test.exs
index c9709f0..7f7f95c 100644
--- a/test/metric/gauge_test.exs
+++ b/test/metric/gauge_test.exs
@@ -1,461 +1,383 @@
defmodule Prometheus.GaugeTest do
use Prometheus.Case
test "registration" do
- spec = [name: :name,
- help: "",
- registry: :qwe]
+ spec = [name: :name, help: "", registry: :qwe]
assert true == Gauge.declare(spec)
assert false == Gauge.declare(spec)
- assert_raise Prometheus.MFAlreadyExistsError,
- "Metric qwe:name already exists.",
- fn ->
+
+ assert_raise Prometheus.MFAlreadyExistsError, "Metric qwe:name already exists.", fn ->
Gauge.new(spec)
end
end
test "spec errors" do
assert_raise Prometheus.MissingMetricSpecKeyError,
- "Required key name is missing from metric spec.",
- fn ->
- Gauge.new([help: ""])
- end
- assert_raise Prometheus.InvalidMetricNameError,
- "Invalid metric name: 12.",
- fn ->
- Gauge.new([name: 12, help: ""])
+ "Required key name is missing from metric spec.",
+ fn ->
+ Gauge.new(help: "")
+ end
+
+ assert_raise Prometheus.InvalidMetricNameError, "Invalid metric name: 12.", fn ->
+ Gauge.new(name: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricLabelsError,
- "Invalid metric labels: 12.",
- fn ->
- Gauge.new([name: "qwe", labels: 12, help: ""])
+
+ assert_raise Prometheus.InvalidMetricLabelsError, "Invalid metric labels: 12.", fn ->
+ Gauge.new(name: "qwe", labels: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricHelpError,
- "Invalid metric help: 12.",
- fn ->
- Gauge.new([name: "qwe", help: 12])
+
+ assert_raise Prometheus.InvalidMetricHelpError, "Invalid metric help: 12.", fn ->
+ Gauge.new(name: "qwe", help: 12)
end
end
test "gauge specific errors" do
- spec = [name: :http_requests_total,
- help: ""]
+ spec = [name: :http_requests_total, help: ""]
## set
assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (set accepts only numbers).",
- fn ->
- Gauge.set(spec, "qwe")
- end
+ "Invalid value: \"qwe\" (set accepts only numbers and 'undefined').",
+ fn ->
+ Gauge.set(spec, "qwe")
+ end
## inc
assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (inc accepts only integers).",
- fn ->
- Gauge.inc(spec, "qwe")
- end
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: -1.5 (inc accepts only integers).",
- fn ->
- Gauge.inc(spec, -1.5)
- end
+ "Invalid value: \"qwe\" (inc accepts only numbers).",
+ fn ->
+ Gauge.inc(spec, "qwe")
+ end
## dec
assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (dec accepts only integers).",
- fn ->
- Gauge.dec(spec, "qwe")
- end
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: -1.5 (dec accepts only integers).",
- fn ->
- Gauge.dec(spec, -1.5)
- end
-
- ## dinc
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (dinc accepts only numbers).",
- fn ->
- Gauge.dinc(spec, "qwe")
- end
-
- ## ddec
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (ddec accepts only numbers).",
- fn ->
- Gauge.ddec(spec, "qwe")
- end
+ "Invalid value: \"qwe\" (dec accepts only numbers).",
+ fn ->
+ Gauge.dec(spec, "qwe")
+ end
## track_inprogress
assert_raise Prometheus.InvalidBlockArityError,
- "Fn with arity 2 (args: :x, :y) passed as block.",
- fn ->
- Macro.expand(quote do
- Gauge.track_inprogress(spec, fn(x, y) -> 1 + x + y end)
- end, __ENV__)
- end
+ "Fn with arity 2 (args: :x, :y) passed as block.",
+ fn ->
+ Macro.expand(
+ quote do
+ Gauge.track_inprogress(spec, fn x, y -> 1 + x + y end)
+ end,
+ __ENV__
+ )
+ end
## set_duration
assert_raise Prometheus.InvalidBlockArityError,
- "Fn with arity 2 (args: :x, :y) passed as block.",
- fn ->
- Macro.expand(quote do
- Gauge.set_duration(spec, fn(x, y) -> 1 + x + y end)
- end, __ENV__)
- end
+ "Fn with arity 2 (args: :x, :y) passed as block.",
+ fn ->
+ Macro.expand(
+ quote do
+ Gauge.set_duration(spec, fn x, y -> 1 + x + y end)
+ end,
+ __ENV__
+ )
+ end
end
test "mf/arity errors" do
- spec = [name: :metric_with_label,
- labels: [:label],
- help: ""]
+ spec = [name: :metric_with_label, labels: [:label], help: ""]
Gauge.declare(spec)
## set
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.set(:unknown_metric, 1)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.set(:unknown_metric, 1)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.set([name: :metric_with_label, labels: [:l1, :l2]], 1)
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.set([name: :metric_with_label, labels: [:l1, :l2]], 1)
+ end
## inc
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.inc(:unknown_metric)
- end
- assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.inc([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.inc(:unknown_metric)
+ end
- ## dinc
- assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.dinc(:unknown_metric)
- end
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.dinc([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.inc(name: :metric_with_label, labels: [:l1, :l2])
+ end
## dec
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.dec(:unknown_metric)
- end
- assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.dec([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.dec(:unknown_metric)
+ end
- ## ddec
- assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.ddec(:unknown_metric)
- end
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.ddec([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.dec(name: :metric_with_label, labels: [:l1, :l2])
+ end
## set_to_current_time
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.set_to_current_time(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.set_to_current_time(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.set_to_current_time([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.set_to_current_time(name: :metric_with_label, labels: [:l1, :l2])
+ end
## track_inprogress
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.track_inprogress(:unknown_metric, fn -> 1 end)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.track_inprogress(:unknown_metric, fn -> 1 end)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.track_inprogress([name: :metric_with_label, labels: [:l1, :l2]], fn -> 1 end)
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.track_inprogress(
+ [name: :metric_with_label, labels: [:l1, :l2]],
+ fn -> 1 end
+ )
+ end
## set_duration
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.set_duration(:unknown_metric, fn -> 1 end)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.set_duration(:unknown_metric, fn -> 1 end)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.set_duration([name: :metric_with_label, labels: [:l1, :l2]], fn -> 1 end)
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.set_duration(
+ [name: :metric_with_label, labels: [:l1, :l2]],
+ fn -> 1 end
+ )
+ end
## remove
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.remove(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.remove(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.remove([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.remove(name: :metric_with_label, labels: [:l1, :l2])
+ end
## reset
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.reset(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.reset(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.reset([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.reset(name: :metric_with_label, labels: [:l1, :l2])
+ end
## value
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Gauge.value(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Gauge.value(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Gauge.value([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Gauge.value(name: :metric_with_label, labels: [:l1, :l2])
+ end
end
test "set" do
- spec = [name: :metric_with_label,
- labels: [:label],
- help: ""]
+ spec = [name: :metric_with_label, labels: [:label], help: ""]
Gauge.declare(spec)
Gauge.set(spec, 100)
assert 100 == Gauge.value(spec)
Gauge.set(spec, 105)
assert 105 == Gauge.value(spec)
Gauge.reset(spec)
assert 0 == Gauge.value(spec)
-
end
test "inc" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Gauge.new(spec)
Gauge.inc(spec)
Gauge.inc(spec, 3)
- assert 4 == Gauge.value(spec)
-
- Gauge.reset(spec)
-
- assert 0 == Gauge.value(spec)
- end
-
- test "dinc" do
- spec = [name: :http_requests_total,
- help: ""]
- Gauge.new(spec)
-
- Gauge.dinc(spec)
- Gauge.dinc(spec, 3.5)
-
- ## dinc is async. let's make sure gen_server processed our request
- Process.sleep(10)
- assert 4.5 == Gauge.value(spec)
+ Gauge.inc(spec)
+ Gauge.inc(spec, 3.5)
+ assert 8.5 == Gauge.value(spec)
Gauge.reset(spec)
assert 0 == Gauge.value(spec)
end
test "dec" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Gauge.new(spec)
Gauge.dec(spec)
Gauge.dec(spec, 3)
- assert (-4 == Gauge.value(spec))
-
- Gauge.reset(spec)
-
- assert 0 == Gauge.value(spec)
- end
-
- test "ddec" do
- spec = [name: :http_requests_total,
- help: ""]
- Gauge.new(spec)
-
- Gauge.ddec(spec)
- Gauge.ddec(spec, 3.5)
+ Gauge.dec(spec)
+ Gauge.dec(spec, 3.5)
- ## ddec is async. let's make sure gen_server processed our request
- Process.sleep(10)
- assert (-4.5 == Gauge.value(spec))
+ assert -8.5 == Gauge.value(spec)
Gauge.reset(spec)
assert 0 == Gauge.value(spec)
end
test "set_to_current_time" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Gauge.new(spec)
Gauge.set_to_current_time(spec)
assert :os.system_time(:seconds) == Gauge.value(spec)
end
test "test_track_inprogress fn" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Gauge.new(spec)
- assert 1 == Gauge.track_inprogress(spec, fn ->
- Gauge.value(spec)
- end)
+ assert 1 ==
+ Gauge.track_inprogress(spec, fn ->
+ Gauge.value(spec)
+ end)
assert_raise ErlangError, fn ->
Gauge.track_inprogress(spec, fn ->
:erlang.error({:qwe})
end)
end
assert 0 = Gauge.value(spec)
end
test "test_track_inprogress block" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Gauge.new(spec)
assert 1 == Gauge.track_inprogress(spec, do: Gauge.value(spec))
assert_raise ErlangError, fn ->
Gauge.track_inprogress spec do
:erlang.error({:qwe})
end
end
assert 0 = Gauge.value(spec)
end
test "set_duration fn" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: "",
- duration_unit: :seconds]
+ spec = [
+ name: :http_requests_total,
+ labels: [:method],
+ help: "",
+ duration_unit: :seconds
+ ]
+
Gauge.new(spec)
- assert 1 == Gauge.set_duration(spec, fn ->
- Process.sleep(1000)
- 1
- end)
+ assert 1 ==
+ Gauge.set_duration(spec, fn ->
+ Process.sleep(1000)
+ 1
+ end)
assert 1 < Gauge.value(spec) and Gauge.value(spec) < 1.2
assert_raise ErlangError, fn ->
Gauge.set_duration(spec, fn ->
:erlang.error({:qwe})
end)
end
assert 0.0 < Gauge.value(spec) and Gauge.value(spec) < 0.2
end
test "set_duration block" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: "",
- duration_unit: :seconds]
+ spec = [
+ name: :http_requests_total,
+ labels: [:method],
+ help: "",
+ duration_unit: :seconds
+ ]
+
Gauge.new(spec)
assert :ok == Gauge.set_duration(spec, do: Process.sleep(1000))
assert 1 < Gauge.value(spec) and Gauge.value(spec) < 1.2
assert_raise ErlangError, fn ->
Gauge.set_duration spec do
:erlang.error({:qwe})
end
end
assert 0.0 < Gauge.value(spec) and Gauge.value(spec) < 0.2
end
test "remove" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- wl_spec = [name: :simple_gauge,
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
+ wl_spec = [name: :simple_gauge, help: ""]
Gauge.new(spec)
Gauge.new(wl_spec)
Gauge.inc(spec)
Gauge.inc(wl_spec)
assert 1 == Gauge.value(spec)
assert 1 == Gauge.value(wl_spec)
assert true == Gauge.remove(spec)
assert true == Gauge.remove(wl_spec)
assert :undefined == Gauge.value(spec)
assert :undefined == Gauge.value(wl_spec)
assert false == Gauge.remove(spec)
assert false == Gauge.remove(wl_spec)
end
test "default value" do
- lspec = [name: :http_requests_gauge,
- labels: [:method],
- help: ""]
+ lspec = [name: :http_requests_gauge, labels: [:method], help: ""]
Gauge.new(lspec)
assert :undefined == Gauge.value(lspec)
- spec = [name: :something_gauge,
- labels: [],
- help: ""]
+ spec = [name: :something_gauge, labels: [], help: ""]
Gauge.new(spec)
assert 0 == Gauge.value(spec)
end
-
end
diff --git a/test/metric/histogram_test.exs b/test/metric/histogram_test.exs
index 739ac8b..5631bd2 100644
--- a/test/metric/histogram_test.exs
+++ b/test/metric/histogram_test.exs
@@ -1,318 +1,270 @@
defmodule Prometheus.HistogramTest do
use Prometheus.Case
test "registration" do
- spec = [name: :name,
- help: "",
- registry: :qwe]
+ spec = [name: :name, help: "", registry: :qwe]
assert true == Histogram.declare(spec)
assert false == Histogram.declare(spec)
- assert_raise Prometheus.MFAlreadyExistsError,
- "Metric qwe:name already exists.",
- fn ->
+
+ assert_raise Prometheus.MFAlreadyExistsError, "Metric qwe:name already exists.", fn ->
Histogram.new(spec)
end
end
test "spec errors" do
assert_raise Prometheus.MissingMetricSpecKeyError,
- "Required key name is missing from metric spec.",
- fn ->
- Histogram.new([help: ""])
- end
- assert_raise Prometheus.InvalidMetricNameError,
- "Invalid metric name: 12.",
- fn ->
- Histogram.new([name: 12, help: ""])
+ "Required key name is missing from metric spec.",
+ fn ->
+ Histogram.new(help: "")
+ end
+
+ assert_raise Prometheus.InvalidMetricNameError, "Invalid metric name: 12.", fn ->
+ Histogram.new(name: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricLabelsError,
- "Invalid metric labels: 12.",
- fn ->
- Histogram.new([name: "qwe", labels: 12, help: ""])
+
+ assert_raise Prometheus.InvalidMetricLabelsError, "Invalid metric labels: 12.", fn ->
+ Histogram.new(name: "qwe", labels: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricHelpError,
- "Invalid metric help: 12.",
- fn ->
- Histogram.new([name: "qwe", help: 12])
+
+ assert_raise Prometheus.InvalidMetricHelpError, "Invalid metric help: 12.", fn ->
+ Histogram.new(name: "qwe", help: 12)
end
+
assert_raise Prometheus.InvalidLabelNameError,
- "Invalid label name: le (histogram cannot have a label named \"le\").",
- fn ->
- Histogram.new([name: "qwe", help: "", labels: ["le"]])
- end
+ "Invalid label name: le (histogram cannot have a label named \"le\").",
+ fn ->
+ Histogram.new(name: "qwe", help: "", labels: ["le"])
+ end
+
## buckets
- assert_raise Prometheus.HistogramNoBucketsError,
- "Invalid histogram buckets: .",
- fn ->
- Histogram.new([name: "qwe", help: "", buckets: []])
- end
- assert_raise Prometheus.HistogramNoBucketsError,
- "Invalid histogram buckets: undefined.",
- fn ->
- Histogram.new([name: "qwe", help: "", buckets: :undefined])
- end
- assert_raise Prometheus.HistogramInvalidBucketsError,
- "Invalid histogram buckets: 1 (not a list).",
- fn ->
- Histogram.new([name: "qwe", help: "", buckets: 1])
- end
- assert_raise Prometheus.HistogramInvalidBucketsError,
- "Invalid histogram buckets: [1,3,2] (buckets not sorted).",
- fn ->
- Histogram.new([name: "qwe", help: "", buckets: [1, 3, 2]])
- end
- assert_raise Prometheus.HistogramInvalidBoundError,
- "Invalid histogram bound: qwe.",
- fn ->
- Histogram.new([name: "qwe", help: "", buckets: ["qwe"]])
+ assert_raise Prometheus.NoBucketsError, "Invalid histogram buckets: .", fn ->
+ Histogram.new(name: "qwe", help: "", buckets: [])
end
+
+ assert_raise Prometheus.NoBucketsError,
+ "Invalid histogram buckets: undefined.",
+ fn ->
+ Histogram.new(name: "qwe", help: "", buckets: :undefined)
+ end
+
+ assert_raise Prometheus.InvalidBucketsError,
+ "Invalid histogram buckets: 1 (not a list).",
+ fn ->
+ Histogram.new(name: "qwe", help: "", buckets: 1)
+ end
+
+ assert_raise Prometheus.InvalidBucketsError,
+ "Invalid histogram buckets: [1,3,2] (buckets not sorted).",
+ fn ->
+ Histogram.new(name: "qwe", help: "", buckets: [1, 3, 2])
+ end
+
+ assert_raise Prometheus.InvalidBoundError,
+ "Invalid histogram bound: qwe.",
+ fn ->
+ Histogram.new(name: "qwe", help: "", buckets: ["qwe"])
+ end
end
test "histogram specific errors" do
- spec = [name: :http_requests_total,
- help: ""]
+ spec = [name: :http_requests_total, help: ""]
## observe
assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (observe accepts only integers).",
- fn ->
- Histogram.observe(spec, "qwe")
- end
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: 1.5 (observe accepts only integers).",
- fn ->
- Histogram.observe(spec, 1.5)
- end
-
- ## dobserve
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (dobserve accepts only numbers).",
- fn ->
- Histogram.dobserve(spec, "qwe")
- end
+ "Invalid value: \"qwe\" (observe accepts only numbers).",
+ fn ->
+ Histogram.observe(spec, "qwe")
+ end
end
test "mf/arity errors" do
- spec = [name: :metric_with_label,
- labels: [:label],
- help: ""]
+ spec = [name: :metric_with_label, labels: [:label], help: ""]
Histogram.declare(spec)
## observe
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Histogram.observe(:unknown_metric, 1)
- end
- assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Histogram.observe([name: :metric_with_label, labels: [:l1, :l2]], 1)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Histogram.observe(:unknown_metric, 1)
+ end
- ## dobserve
- assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Histogram.dobserve(:unknown_metric)
- end
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Histogram.dobserve([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Histogram.observe([name: :metric_with_label, labels: [:l1, :l2]], 1)
+ end
## observe_duration
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Histogram.observe_duration(:unknown_metric, fn -> 1 end)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Histogram.observe_duration(:unknown_metric, fn -> 1 end)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Histogram.observe_duration(
- [name: :metric_with_label, labels: [:l1, :l2]], fn -> 1 end)
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Histogram.observe_duration(
+ [name: :metric_with_label, labels: [:l1, :l2]],
+ fn -> 1 end
+ )
+ end
## remove
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Histogram.remove(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Histogram.remove(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Histogram.remove([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Histogram.remove(name: :metric_with_label, labels: [:l1, :l2])
+ end
## reset
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Histogram.reset(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Histogram.reset(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Histogram.reset([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Histogram.reset(name: :metric_with_label, labels: [:l1, :l2])
+ end
## value
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Histogram.value(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Histogram.value(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Histogram.value([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ 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
+ "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
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Histogram.new(spec)
Histogram.observe(spec)
Histogram.observe(spec, 3)
- assert {[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0], 4} == Histogram.value(spec)
-
- Histogram.reset(spec)
-
- assert {[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0} == Histogram.value(spec)
- end
-
- test "dobserve" do
- spec = [name: :http_requests_total,
- help: ""]
- Histogram.new(spec)
-
- Histogram.dobserve(spec)
- Histogram.dobserve(spec, 3.5)
+ Histogram.observe(spec)
+ Histogram.observe(spec, 3.5)
- ## dobserve is async. let's make sure gen_server processed our request
- Process.sleep(10)
- assert {[0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0], 4.5} == Histogram.value(spec)
+ assert {[0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0], 8.5} == Histogram.value(spec)
Histogram.reset(spec)
assert {[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 0} == Histogram.value(spec)
end
test "observe_duration fn" do
- spec = [name: :duration_seconds,
- labels: [:method],
- help: ""]
+ spec = [name: :duration_seconds, labels: [:method], help: ""]
Histogram.new(spec)
- assert 1 == Histogram.observe_duration(spec, fn ->
- Process.sleep(1000)
- 1
- end)
+ assert 1 ==
+ Histogram.observe_duration(spec, fn ->
+ Process.sleep(1000)
+ 1
+ end)
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{buckets, sum} = Histogram.value(spec)
assert [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0] == buckets
assert 1 < sum and sum < 1.2
assert_raise ErlangError, fn ->
Histogram.observe_duration(spec, fn ->
:erlang.error({:qwe})
end)
end
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{buckets, sum} = Histogram.value(spec)
assert [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0] == buckets
assert 1 < sum and sum < 1.2
end
test "observe_duration block" do
- spec = [name: :duration_seconds,
- labels: [:method],
- help: ""]
+ spec = [name: :duration_seconds, labels: [:method], help: ""]
Histogram.new(spec)
assert :ok == Histogram.observe_duration(spec, do: Process.sleep(1000))
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{buckets, sum} = Histogram.value(spec)
assert [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0] == buckets
assert 1 < sum and sum < 1.2
assert_raise ErlangError, fn ->
Histogram.observe_duration spec do
:erlang.error({:qwe})
end
end
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{buckets, sum} = Histogram.value(spec)
assert [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0] == buckets
assert 1 < sum and sum < 1.2
end
test "remove" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- wl_spec = [name: :simple_histogram,
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
+ wl_spec = [name: :simple_histogram, help: ""]
Histogram.new(spec)
Histogram.new(wl_spec)
Histogram.observe(spec)
Histogram.observe(wl_spec)
assert {[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 1} == Histogram.value(spec)
assert {[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], 1} == Histogram.value(wl_spec)
assert true == Histogram.remove(spec)
assert true == Histogram.remove(wl_spec)
assert :undefined == Histogram.value(spec)
assert :undefined == Histogram.value(wl_spec)
assert false == Histogram.remove(spec)
assert false == Histogram.remove(wl_spec)
end
test "undefined value" do
- lspec = [name: :duraiton_histogram,
- labels: [:method],
- buckets: [5, 10],
- help: ""]
+ lspec = [name: :duraiton_histogram, labels: [:method], buckets: [5, 10], help: ""]
Histogram.new(lspec)
assert :undefined == Histogram.value(lspec)
- spec = [name: :something_histogram,
- labels: [],
- buckets: [5, 10],
- help: ""]
+ spec = [name: :something_histogram, labels: [], buckets: [5, 10], help: ""]
Histogram.new(spec)
assert {[0, 0, 0], 0} == Histogram.value(spec)
end
-
end
diff --git a/test/metric/summary_test.exs b/test/metric/summary_test.exs
index c01e3aa..34475c0 100644
--- a/test/metric/summary_test.exs
+++ b/test/metric/summary_test.exs
@@ -1,290 +1,241 @@
defmodule Prometheus.SummaryTest do
use Prometheus.Case
test "registration" do
- spec = [name: :name,
- help: "",
- registry: :qwe]
+ spec = [name: :name, help: "", registry: :qwe]
assert true == Summary.declare(spec)
assert false == Summary.declare(spec)
- assert_raise Prometheus.MFAlreadyExistsError,
- "Metric qwe:name already exists.",
- fn ->
+
+ assert_raise Prometheus.MFAlreadyExistsError, "Metric qwe:name already exists.", fn ->
Summary.new(spec)
end
end
test "spec errors" do
assert_raise Prometheus.MissingMetricSpecKeyError,
- "Required key name is missing from metric spec.",
- fn ->
- Summary.new([help: ""])
- end
- assert_raise Prometheus.InvalidMetricNameError,
- "Invalid metric name: 12.",
- fn ->
- Summary.new([name: 12, help: ""])
+ "Required key name is missing from metric spec.",
+ fn ->
+ Summary.new(help: "")
+ end
+
+ assert_raise Prometheus.InvalidMetricNameError, "Invalid metric name: 12.", fn ->
+ Summary.new(name: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricLabelsError,
- "Invalid metric labels: 12.",
- fn ->
- Summary.new([name: "qwe", labels: 12, help: ""])
+
+ assert_raise Prometheus.InvalidMetricLabelsError, "Invalid metric labels: 12.", fn ->
+ Summary.new(name: "qwe", labels: 12, help: "")
end
- assert_raise Prometheus.InvalidMetricHelpError,
- "Invalid metric help: 12.",
- fn ->
- Summary.new([name: "qwe", help: 12])
+
+ assert_raise Prometheus.InvalidMetricHelpError, "Invalid metric help: 12.", fn ->
+ Summary.new(name: "qwe", help: 12)
end
+
assert_raise Prometheus.InvalidLabelNameError,
- "Invalid label name: quantile (summary cannot have a label named \"quantile\").",
- fn ->
- Summary.new([name: "qwe", help: "", labels: ["quantile"]])
- end
+ "Invalid label name: quantile (summary cannot have a label named \"quantile\").",
+ fn ->
+ Summary.new(name: "qwe", help: "", labels: ["quantile"])
+ end
end
test "summary specific errors" do
- spec = [name: :http_requests_total,
- help: ""]
+ spec = [name: :http_requests_total, help: ""]
## observe
assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (observe accepts only integers).",
- fn ->
- Summary.observe(spec, "qwe")
- end
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: 1.5 (observe accepts only integers).",
- fn ->
- Summary.observe(spec, 1.5)
- end
-
- ## dobserve
- assert_raise Prometheus.InvalidValueError,
- "Invalid value: \"qwe\" (dobserve accepts only numbers).",
- fn ->
- Summary.dobserve(spec, "qwe")
- end
+ "Invalid value: \"qwe\" (observe accepts only numbers).",
+ fn ->
+ Summary.observe(spec, "qwe")
+ end
## observe_duration TODO: assert_compile_time_raise
assert_raise Prometheus.InvalidBlockArityError,
- "Fn with arity 2 (args: :x, :y) passed as block.",
- fn ->
- Macro.expand(quote do
- Summary.observe_duration(spec, fn(x, y) -> 1 + x + y end)
- end, __ENV__)
- end
+ "Fn with arity 2 (args: :x, :y) passed as block.",
+ fn ->
+ Macro.expand(
+ quote do
+ Summary.observe_duration(spec, fn x, y -> 1 + x + y end)
+ end,
+ __ENV__
+ )
+ end
end
test "mf/arity errors" do
- spec = [name: :metric_with_label,
- labels: [:label],
- help: ""]
+ spec = [name: :metric_with_label, labels: [:label], help: ""]
Summary.declare(spec)
## observe
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Summary.observe(:unknown_metric, 1)
- end
- assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Summary.observe([name: :metric_with_label, labels: [:l1, :l2]], 1)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Summary.observe(:unknown_metric, 1)
+ end
- ## dobserve
- assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Summary.dobserve(:unknown_metric)
- end
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Summary.dobserve([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Summary.observe([name: :metric_with_label, labels: [:l1, :l2]], 1)
+ end
## observe_duration
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Summary.observe_duration(:unknown_metric, fn -> 1 end)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Summary.observe_duration(:unknown_metric, fn -> 1 end)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Summary.observe_duration(
- [name: :metric_with_label, labels: [:l1, :l2]], fn -> 1 end)
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Summary.observe_duration(
+ [name: :metric_with_label, labels: [:l1, :l2]],
+ fn -> 1 end
+ )
+ end
## remove
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Summary.remove(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Summary.remove(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Summary.remove([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Summary.remove(name: :metric_with_label, labels: [:l1, :l2])
+ end
## reset
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Summary.reset(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Summary.reset(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Summary.reset([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Summary.reset(name: :metric_with_label, labels: [:l1, :l2])
+ end
## value
assert_raise Prometheus.UnknownMetricError,
- "Unknown metric {registry: default, name: unknown_metric}.",
- fn ->
- Summary.value(:unknown_metric)
- end
+ "Unknown metric {registry: default, name: unknown_metric}.",
+ fn ->
+ Summary.value(:unknown_metric)
+ end
+
assert_raise Prometheus.InvalidMetricArityError,
- "Invalid metric arity: got 2, expected 1.",
- fn ->
- Summary.value([name: :metric_with_label, labels: [:l1, :l2]])
- end
+ "Invalid metric arity: got 2, expected 1.",
+ fn ->
+ Summary.value(name: :metric_with_label, labels: [:l1, :l2])
+ end
end
test "observe" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
Summary.new(spec)
Summary.observe(spec)
Summary.observe(spec, 3)
- assert {2, 4} == Summary.value(spec)
-
- Summary.reset(spec)
-
- assert {0, 0} == Summary.value(spec)
- end
-
- test "dobserve" do
- spec = [name: :http_requests_total,
- help: ""]
- Summary.new(spec)
+ Summary.observe(spec)
+ Summary.observe(spec, 3.5)
- Summary.dobserve(spec)
- Summary.dobserve(spec, 3.5)
-
- ## dobserve is async. let's make sure gen_server processed our increment request
- Process.sleep(10)
- assert {2, 4.5} == Summary.value(spec)
+ assert {4, 8.5} == Summary.value(spec)
Summary.reset(spec)
assert {0, 0} == Summary.value(spec)
end
test "observe_duration fn" do
- spec = [name: :duration_seconds,
- labels: [:method],
- help: ""]
+ spec = [name: :duration_seconds, labels: [:method], help: ""]
Summary.new(spec)
- assert 1 == Summary.observe_duration(spec, fn ->
- Process.sleep(1000)
- 1
- end)
+ assert 1 ==
+ Summary.observe_duration(spec, fn ->
+ Process.sleep(1000)
+ 1
+ end)
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{count, sum} = Summary.value(spec)
assert 1 == count
assert 1 < sum and sum < 1.2
assert_raise ErlangError, fn ->
Summary.observe_duration(spec, fn ->
:erlang.error({:qwe})
end)
end
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{count, sum} = Summary.value(spec)
assert 2 == count
assert 1 < sum and sum < 1.2
end
test "observe_duration block" do
- spec = [name: :duration_seconds,
- labels: [:method],
- help: ""]
+ spec = [name: :duration_seconds, labels: [:method], help: ""]
Summary.new(spec)
assert :ok == Summary.observe_duration(spec, do: Process.sleep(1000))
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{count, sum} = Summary.value(spec)
assert 1 == count
assert 1 < sum and sum < 1.2
assert_raise ErlangError, fn ->
Summary.observe_duration spec do
:erlang.error({:qwe})
end
end
## observe_duration is async. let's make sure gen_server processed our request
Process.sleep(10)
{count, sum} = Summary.value(spec)
assert 2 == count
assert 1 < sum and sum < 1.2
end
test "remove" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- wl_spec = [name: :simple_summary,
- help: ""]
+ spec = [name: :http_requests_total, labels: [:method], help: ""]
+ wl_spec = [name: :simple_summary, help: ""]
Summary.new(spec)
Summary.new(wl_spec)
Summary.observe(spec)
Summary.observe(wl_spec)
assert {1, 1} == Summary.value(spec)
assert {1, 1} == Summary.value(wl_spec)
assert true == Summary.remove(spec)
assert true == Summary.remove(wl_spec)
assert :undefined == Summary.value(spec)
assert :undefined == Summary.value(wl_spec)
assert false == Summary.remove(spec)
assert false == Summary.remove(wl_spec)
end
test "undefined value" do
- lspec = [name: :orders_summary,
- labels: [:department],
- help: ""]
+ lspec = [name: :orders_summary, labels: [:department], help: ""]
Summary.new(lspec)
assert :undefined == Summary.value(lspec)
- spec = [name: :something_summary,
- labels: [],
- help: ""]
+ spec = [name: :something_summary, labels: [], help: ""]
Summary.new(spec)
assert {0, 0} == Summary.value(spec)
end
-
end
diff --git a/test/metric_test.exs b/test/metric_test.exs
index 5c3ccaa..ef0b410 100644
--- a/test/metric_test.exs
+++ b/test/metric_test.exs
@@ -1,70 +1,81 @@
defmodule Prometheus.MetricTest do
use Prometheus.Case
doctest Prometheus.Metric
defmacro __before_compile__(_env) do
quote do
def injected_fun() do
1
end
end
end
test "@metric attributes leads to metric declaration" do
defmodule ModuleWithMetrics do
use Prometheus.Metric
@before_compile Prometheus.MetricTest
@counter name: :test_counter1, labels: [], help: "qwe"
@counter name: :test_counter2, labels: [:tag], help: "qwa"
@gauge name: :test_gauge1, labels: [], help: "qwe"
@gauge name: :test_gauge2, labels: [:tag], help: "qwa"
@boolean name: :test_boolean1, labels: [], help: "qwe"
@boolean name: :test_boolean2, labels: [:tag], help: "qwa"
@summary name: :test_summary1, labels: [], help: "qwe"
@summary name: :test_summary2, labels: [:tag], help: "qwa"
- @histogram name: :test_histogram1, labels: [], buckets: [1, 2], help: "qwe"
+ @histogram name: :test_histogram1, labels: [], buckets: [1, 2], help: "qwe"
@histogram name: :test_histogram2, labels: [:tag], buckets: [1, 2], help: "qwa"
@on_load :custom_on_load_fun
def custom_on_load_fun() do
Counter.declare(name: :custom_counter, labels: [], help: "qwe")
:ok
end
end
defmodule ModuleWithoutOnLoad do
use Prometheus.Metric
@counter name: :test_counter3, labels: [], help: "qwe"
end
assert 1 == ModuleWithMetrics.injected_fun()
assert false == Counter.declare(name: :custom_counter, labels: [], help: "qwe")
assert false == Counter.declare(name: :test_counter3, labels: [], help: "qwe")
assert false == Counter.declare(name: :test_counter1, labels: [], help: "qwe")
assert false == Counter.declare(name: :test_counter2, labels: [:tag], help: "qwa")
assert false == Gauge.declare(name: :test_gauge1, labels: [], help: "qwe")
assert false == Gauge.declare(name: :test_gauge2, labels: [:tag], help: "qwa")
assert false == Boolean.declare(name: :test_boolean1, labels: [], help: "qwe")
assert false == Boolean.declare(name: :test_boolean2, labels: [:tag], help: "qwa")
assert false == Summary.declare(name: :test_summary1, labels: [], help: "qwe")
assert false == Summary.declare(name: :test_summary2, labels: [:tag], help: "qwa")
assert false ==
- Histogram.declare(name: :test_histogram1, labels: [], buckets: [1, 2], help: "")
+ Histogram.declare(
+ name: :test_histogram1,
+ labels: [],
+ buckets: [1, 2],
+ help: ""
+ )
+
assert false ==
- Histogram.declare(name: :test_histogram2, labels: [:tag], buckets: [1, 2], help: "")
+ Histogram.declare(
+ name: :test_histogram2,
+ labels: [:tag],
+ buckets: [1, 2],
+ help: ""
+ )
end
end
diff --git a/test/model_test.exs b/test/model_test.exs
index b3b25bc..ff3244e 100644
--- a/test/model_test.exs
+++ b/test/model_test.exs
@@ -1,21 +1,26 @@
defmodule Prometheus.ModelTest do
-
use Prometheus.Case
require Prometheus.Model
doctest Prometheus.Model
def collect_metrics(:pool_size, _) do
Prometheus.Model.untyped_metric(365)
end
test "create_mf" do
assert {:MetricFamily, <<"pool_size">>, <<"help">>, :UNTYPED,
- [{:Metric, [], :undefined, :undefined, :undefined,
- {:Untyped, 365},
- :undefined, :undefined}]} ==
- Prometheus.Model.create_mf(
- :pool_size, "help", :untyped, Prometheus.ModelTest, :undefined)
+ [
+ {:Metric, [], :undefined, :undefined, :undefined, {:Untyped, 365},
+ :undefined, :undefined}
+ ]} ==
+ Prometheus.Model.create_mf(
+ :pool_size,
+ "help",
+ :untyped,
+ Prometheus.ModelTest,
+ :undefined
+ )
end
end
diff --git a/test/registry_test.exs b/test/registry_test.exs
index 0368334..2f61609 100644
--- a/test/registry_test.exs
+++ b/test/registry_test.exs
@@ -1,69 +1,71 @@
defmodule Prometheus.RegistryTest do
-
use Prometheus.Case
alias Prometheus.Registry
alias Prometheus.RegistryTest
import ExUnit.CaptureIO
def deregister_cleanup(_), do: :ok
test "registry exists" do
Prometheus.Registry.register_collector(:test_registry, RegistryTest)
assert true == Registry.exists(:test_registry)
assert :test_registry == Registry.exists("test_registry")
assert false == Registry.exists(:qweqwe)
assert false == Registry.exists("qweqwe")
end
test "default Registry" do
# default registry
assert :ok == Prometheus.Registry.register_collector(RegistryTest)
assert [RegistryTest] == Registry.collectors()
assert true == Registry.collector_registered?(RegistryTest)
Registry.clear()
assert [] == Registry.collectors()
assert false == Registry.collector_registered?(RegistryTest)
assert :ok == Registry.register_collector(RegistryTest)
Registry.deregister_collector(RegistryTest)
assert [] == Registry.collectors()
assert false == Registry.collector_registered?(RegistryTest)
## custom registry
assert :ok == Registry.register_collector(:custom_collector, RegistryTest)
assert [RegistryTest] == Registry.collectors(:custom_collector)
assert true == Registry.collector_registered?(:custom_collector, RegistryTest)
Registry.clear(:custom_collector)
assert [] == Registry.collectors(:custom_collector)
assert false == Registry.collector_registered?(:custom_collector, RegistryTest)
assert :ok == Registry.register_collector(:custom_collector, RegistryTest)
Registry.deregister_collector(:custom_collector, RegistryTest)
assert [] == Registry.collectors(:custom_collector)
assert false == Registry.collector_registered?(:custom_collector, RegistryTest)
## register_collectors && collect; default registry
assert :ok == Registry.register_collectors([RegistryTest])
assert [RegistryTest] == Registry.collectors()
+
assert capture_io(fn ->
- Registry.collect(fn (:default, collector) ->
- :io.format("~p", [collector])
- end) ==
- "Elixir.RegistryTest"
- end)
+ Registry.collect(fn :default, collector ->
+ :io.format("~p", [collector])
+ end) == "Elixir.RegistryTest"
+ end)
## register_collectors && collect; custom registry
assert :ok == Registry.register_collectors(:custom_collector, [RegistryTest])
assert [RegistryTest] == Registry.collectors(:custom_collector)
+
assert capture_io(fn ->
- Registry.collect(fn (:custom_collector, collector) ->
- :io.format("~p", [collector])
- end, :custom_collector) ==
- "Elixir.RegistryTest"
- end)
+ Registry.collect(
+ fn :custom_collector, collector ->
+ :io.format("~p", [collector])
+ end,
+ :custom_collector
+ ) == "Elixir.RegistryTest"
+ end)
end
end
diff --git a/test/test_helper.exs b/test/test_helper.exs
index d8b7989..a054dfa 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -1,25 +1,23 @@
ExUnit.start()
defmodule Prometheus.Case do
defmacro __using__(_opts) do
quote do
-
use ExUnit.Case
use Prometheus
import ExUnit.CaptureIO
setup do
collectors = Prometheus.Registry.collectors()
Prometheus.Registry.clear()
Prometheus.Registry.clear(:qwe)
- on_exit fn ->
+ on_exit(fn ->
Prometheus.Registry.clear()
Prometheus.Registry.clear(:qwe)
Prometheus.Registry.register_collectors(collectors)
- end
+ end)
end
-
end
end
end

File Metadata

Mime Type
text/x-diff
Expires
Wed, Nov 27, 5:57 PM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40706
Default Alt Text
(199 KB)

Event Timeline