Page MenuHomePhorge

No OneTemporary

Size
42 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/prometheus/metric/counter.ex b/lib/prometheus/metric/counter.ex
index a724b6f..e13141f 100644
--- a/lib/prometheus/metric/counter.ex
+++ b/lib/prometheus/metric/counter.ex
@@ -1,147 +1,147 @@
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.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 `value`.
If `value` happened to be a float number even one time(!) you
shouldn't use `inc/2` after dinc.
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])
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({:prometheus_counter, :value}, spec)
+ Erlang.metric_call(spec)
end
end
diff --git a/test/metric/counter_test.exs b/test/metric/counter_test.exs
index 44dd0b4..c763151 100644
--- a/test/metric/counter_test.exs
+++ b/test/metric/counter_test.exs
@@ -1,209 +1,216 @@
defmodule Prometheus.CounterTest do
use Prometheus.Case
test "registration" do
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 ->
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: ""])
end
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])
end
end
test "counter specific errors" do
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).",
+ "Invalid value: \"qwe\" (inc accepts only non-negative integers).",
fn ->
Counter.inc(spec, "qwe")
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).",
+ "Invalid value: \"qwe\" (dinc accepts only non-negative numbers).",
fn ->
Counter.dinc(spec, "qwe")
end
end
test "mf/arity errors" do
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
## 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
## remove
assert_raise Prometheus.UnknownMetricError,
"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
## reset
assert_raise Prometheus.UnknownMetricError,
"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
## value
assert_raise Prometheus.UnknownMetricError,
"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
end
test "inc" do
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)
## dinc is async. let's make sure gen_server processed our request
Process.sleep(10)
assert 4.5 == Counter.value(spec)
Counter.reset(spec)
assert 0 == Counter.value(spec)
end
- test "undefined value" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- Counter.new(spec)
-
- assert :undefined == Counter.value(spec)
- end
-
test "remove" do
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: ""]
+ Counter.new(lspec)
+
+ assert :undefined == Counter.value(lspec)
+
+ spec = [name: :something_total,
+ labels: [],
+ help: ""]
+ Counter.new(spec)
+
+ assert 0 == Counter.value(spec)
+ end
+
end
diff --git a/test/metric/gauge_test.exs b/test/metric/gauge_test.exs
index 273a1ec..3e99e43 100644
--- a/test/metric/gauge_test.exs
+++ b/test/metric/gauge_test.exs
@@ -1,451 +1,458 @@
defmodule Prometheus.GaugeTest do
use Prometheus.Case
test "registration" do
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 ->
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: ""])
end
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])
end
end
test "gauge specific errors" do
spec = [name: :http_requests_total,
help: ""]
## set
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (set accepts only numbers).",
+ "Invalid value: \"qwe\" (set accepts only numbers).",
fn ->
Gauge.set(spec, "qwe")
end
## inc
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (inc accepts only integers).",
+ "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
## dec
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (dec accepts only integers).",
+ "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).",
+ "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).",
+ "Invalid value: \"qwe\" (ddec accepts only numbers).",
fn ->
Gauge.ddec(spec, "qwe")
end
## track_inprogress
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (track_inprogress accepts only functions).",
+ "Invalid value: \"qwe\" (track_inprogress accepts only functions).",
fn ->
Gauge.track_inprogress(spec, "qwe")
end
## set_duration
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (set_duration accepts only functions).",
+ "Invalid value: \"qwe\" (set_duration accepts only functions).",
fn ->
Gauge.set_duration(spec, "qwe")
end
end
test "mf/arity errors" do
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
assert_raise Prometheus.InvalidMetricArityError,
"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
## 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
## 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
## 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
## set_to_current_time
assert_raise Prometheus.UnknownMetricError,
"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
## track_inprogress
assert_raise Prometheus.UnknownMetricError,
"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
## set_duration
assert_raise Prometheus.UnknownMetricError,
"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
## remove
assert_raise Prometheus.UnknownMetricError,
"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
## reset
assert_raise Prometheus.UnknownMetricError,
"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
## value
assert_raise Prometheus.UnknownMetricError,
"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
end
test "set" do
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: ""]
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.reset(spec)
assert 0 == Gauge.value(spec)
end
test "dec" do
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)
## ddec is async. let's make sure gen_server processed our request
Process.sleep(10)
assert -4.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: ""]
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: ""]
Gauge.new(spec)
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: ""]
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]
Gauge.new(spec)
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]
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 "undefined value" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- Gauge.new(spec)
-
- assert :undefined == Gauge.value(spec)
- end
-
test "remove" do
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: ""]
+ Gauge.new(lspec)
+
+ assert :undefined == Gauge.value(lspec)
+
+ 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 8fc0d8b..b53cb0b 100644
--- a/test/metric/histogram_test.exs
+++ b/test/metric/histogram_test.exs
@@ -1,307 +1,316 @@
defmodule Prometheus.HistogramTest do
use Prometheus.Case
test "registration" do
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 ->
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: ""])
end
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])
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
## 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"]])
end
end
test "histogram specific errors" do
spec = [name: :http_requests_total,
help: ""]
## observe
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (observe accepts only integers).",
+ "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).",
+ "Invalid value: \"qwe\" (dobserve accepts only numbers).",
fn ->
Histogram.dobserve(spec, "qwe")
end
## observe_duration
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (observe_duration accepts only functions).",
+ "Invalid value: \"qwe\" (observe_duration accepts only functions).",
fn ->
Histogram.observe_duration(spec, "qwe")
end
end
test "mf/arity errors" do
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
## 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
## observe_duration
assert_raise Prometheus.UnknownMetricError,
"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
## remove
assert_raise Prometheus.UnknownMetricError,
"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
## reset
assert_raise Prometheus.UnknownMetricError,
"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
## value
assert_raise Prometheus.UnknownMetricError,
"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
end
test "observe" do
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)
## 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)
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: ""]
Histogram.new(spec)
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: ""]
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 "undefined value" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- Histogram.new(spec)
-
- assert :undefined == Histogram.value(spec)
- end
-
test "remove" do
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: ""]
+ Histogram.new(lspec)
+
+ assert :undefined == Histogram.value(lspec)
+
+ 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 5e49d2d..7f87dfb 100644
--- a/test/metric/summary_test.exs
+++ b/test/metric/summary_test.exs
@@ -1,281 +1,288 @@
defmodule Prometheus.SummaryTest do
use Prometheus.Case
test "registration" do
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 ->
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: ""])
end
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])
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
end
test "summary specific errors" do
spec = [name: :http_requests_total,
help: ""]
## observe
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (observe accepts only integers).",
+ "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).",
+ "Invalid value: \"qwe\" (dobserve accepts only numbers).",
fn ->
Summary.dobserve(spec, "qwe")
end
## observe_duration
assert_raise Prometheus.InvalidValueError,
- "Invalid value: qwe (observe_duration accepts only functions).",
+ "Invalid value: \"qwe\" (observe_duration accepts only functions).",
fn ->
Summary.observe_duration(spec, "qwe")
end
end
test "mf/arity errors" do
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
## 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
## observe_duration
assert_raise Prometheus.UnknownMetricError,
"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
## remove
assert_raise Prometheus.UnknownMetricError,
"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
## reset
assert_raise Prometheus.UnknownMetricError,
"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
## value
assert_raise Prometheus.UnknownMetricError,
"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
end
test "observe" do
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.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)
Summary.reset(spec)
assert {0, 0} == Summary.value(spec)
end
test "observe_duration fn" do
spec = [name: :duration_seconds,
labels: [:method],
help: ""]
Summary.new(spec)
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: ""]
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 "undefined value" do
- spec = [name: :http_requests_total,
- labels: [:method],
- help: ""]
- Summary.new(spec)
-
- assert :undefined == Summary.value(spec)
- end
-
test "remove" do
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: ""]
+ Summary.new(lspec)
+
+ assert :undefined == Summary.value(lspec)
+
+ spec = [name: :something_summary,
+ labels: [],
+ help: ""]
+ Summary.new(spec)
+
+ assert {0, 0} == Summary.value(spec)
+ end
+
end

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 30, 2:44 AM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41345
Default Alt Text
(42 KB)

Event Timeline