diff --git a/lib/telemetry_metrics.ex b/lib/telemetry_metrics.ex index 85514a2..4de2092 100644 --- a/lib/telemetry_metrics.ex +++ b/lib/telemetry_metrics.ex @@ -68,10 +68,12 @@ defmodule Telemetry.Metrics do * `:tag_values` - a function that receives the metadata and returns a map with the tags as keys and their respective values. Defaults to returning the metadata itself. - * `:keep` - a predicate function that evaluates the metadata to conditionally - record a given event. `:keep` and `:drop` cannot be combined. Defaults to `nil`. - * `:drop` - a predicate function that evaluates the metadata to conditionally - skip recording a given event. `:keep` and `:drop` cannot be combined. Defaults to `nil`. + * `:keep` - a predicate function that evaluates the metadata and measurement + to conditionally record a given event. `:keep` and `:drop` cannot be + combined. Defaults to `nil`. + * `:drop` - a predicate function that evaluates the metadata and measurement + to conditionally skip recording a given event. `:keep` and `:drop` cannot + be combined. Defaults to `nil`. * `:description` - human-readable description of the metric. Might be used by reporters for documentation purposes. Defaults to `nil`. * `:unit` - an atom describing the unit of selected measurement, typically in @@ -408,7 +410,9 @@ defmodule Telemetry.Metrics do @type tag :: term() @type tags :: [tag()] @type tag_values :: (:telemetry.event_metadata() -> :telemetry.event_metadata()) - @type keep :: (:telemetry.event_metadata() -> boolean()) + @type keep :: + (:telemetry.event_metadata() -> boolean()) + | (:telemetry.event_metadata(), :telemetry.event_measurements() -> boolean()) @type drop :: (:telemetry.event_metadata() -> boolean()) @type description :: nil | String.t() @type unit :: atom() @@ -614,11 +618,11 @@ defmodule Telemetry.Metrics do end defp validate_recording_rule_fun!(nil), do: nil - defp validate_recording_rule_fun!(fun) when is_function(fun, 1), do: fun + defp validate_recording_rule_fun!(fun) when is_function(fun, 1) or is_function(fun, 2), do: fun defp validate_recording_rule_fun!(term) do raise ArgumentError, - "expected recording rule to be a function accepting metadata, got #{inspect(term)}" + "expected recording rule to be a function accepting either metadata or metadata and measurements, got #{inspect(term)}" end defp validate_recording_rule_fun_options!(keep, drop) when is_nil(keep) or is_nil(drop), do: :ok @@ -629,8 +633,9 @@ defmodule Telemetry.Metrics do end defp keep_fun(nil, nil), do: nil - defp keep_fun(nil, drop), do: fn meta -> not drop.(meta) end defp keep_fun(keep, nil), do: keep + defp keep_fun(nil, drop) when is_function(drop, 1), do: &(not drop.(&1)) + defp keep_fun(nil, drop) when is_function(drop, 2), do: &(not drop.(&1, &2)) @spec fill_in_default_metric_options([metric_option()]) :: [metric_option()] defp fill_in_default_metric_options(options) do diff --git a/lib/telemetry_metrics/console_reporter.ex b/lib/telemetry_metrics/console_reporter.ex index eaa10a0..813c3f0 100644 --- a/lib/telemetry_metrics/console_reporter.ex +++ b/lib/telemetry_metrics/console_reporter.ex @@ -100,7 +100,7 @@ defmodule Telemetry.Metrics.ConsoleReporter do Measurement value missing (metric skipped) """ - not keep?(metric, metadata) -> + not keep?(metric, metadata, measurements) -> """ Event dropped """ @@ -142,8 +142,13 @@ defmodule Telemetry.Metrics.ConsoleReporter do "#{inspect(measurement)} [via #{inspect(fun)}]" end - defp keep?(%{keep: nil}, _metadata), do: true - defp keep?(metric, metadata), do: metric.keep.(metadata) + defp keep?(metric, metadata, measurements) do + case metric do + %{keep: nil} -> true + %{keep: keep} when is_function(keep, 1) -> keep.(metadata) + %{keep: keep} when is_function(keep, 2) -> keep.(metadata, measurements) + end + end defp extract_measurement(metric, measurements, metadata) do case metric.measurement do diff --git a/lib/telemetry_metrics/counter.ex b/lib/telemetry_metrics/counter.ex index 54bbee6..3bc3ad1 100644 --- a/lib/telemetry_metrics/counter.ex +++ b/lib/telemetry_metrics/counter.ex @@ -22,8 +22,8 @@ defmodule Telemetry.Metrics.Counter do event_name: :telemetry.event_name(), measurement: Metrics.measurement(), tags: Metrics.tags(), - tag_values: (:telemetry.event_metadata() -> :telemetry.event_metadata()), - keep: (:telemetry.event_metadata() -> boolean()), + tag_values: Metrics.tag_values(), + keep: Metrics.keep(), description: Metrics.description(), unit: Metrics.unit(), reporter_options: Metrics.reporter_options() diff --git a/lib/telemetry_metrics/distribution.ex b/lib/telemetry_metrics/distribution.ex index 5af70a2..a69048f 100644 --- a/lib/telemetry_metrics/distribution.ex +++ b/lib/telemetry_metrics/distribution.ex @@ -22,8 +22,8 @@ defmodule Telemetry.Metrics.Distribution do event_name: :telemetry.event_name(), measurement: Metrics.measurement(), tags: Metrics.tags(), - tag_values: (:telemetry.event_metadata() -> :telemetry.event_metadata()), - keep: (:telemetry.event_metadata() -> boolean()), + tag_values: Metrics.tag_values(), + keep: Metrics.keep(), description: Metrics.description(), unit: Metrics.unit(), reporter_options: Metrics.reporter_options() diff --git a/lib/telemetry_metrics/last_value.ex b/lib/telemetry_metrics/last_value.ex index 8a3277d..95cdccb 100644 --- a/lib/telemetry_metrics/last_value.ex +++ b/lib/telemetry_metrics/last_value.ex @@ -22,8 +22,8 @@ defmodule Telemetry.Metrics.LastValue do event_name: :telemetry.event_name(), measurement: Metrics.measurement(), tags: Metrics.tags(), - tag_values: (:telemetry.event_metadata() -> :telemetry.event_metadata()), - keep: (:telemetry.event_metadata() -> boolean()), + tag_values: Metrics.tag_values(), + keep: Metrics.keep(), description: Metrics.description(), unit: Metrics.unit(), reporter_options: Metrics.reporter_options() diff --git a/lib/telemetry_metrics/sum.ex b/lib/telemetry_metrics/sum.ex index 169f846..12f3512 100644 --- a/lib/telemetry_metrics/sum.ex +++ b/lib/telemetry_metrics/sum.ex @@ -22,8 +22,8 @@ defmodule Telemetry.Metrics.Sum do event_name: :telemetry.event_name(), measurement: Metrics.measurement(), tags: Metrics.tags(), - tag_values: (:telemetry.event_metadata() -> :telemetry.event_metadata()), - keep: (:telemetry.event_metadata() -> boolean()), + tag_values: Metrics.tag_values(), + keep: Metrics.keep(), description: Metrics.description(), unit: Metrics.unit(), reporter_options: Metrics.reporter_options() diff --git a/lib/telemetry_metrics/summary.ex b/lib/telemetry_metrics/summary.ex index 502ccef..fb4b2c5 100644 --- a/lib/telemetry_metrics/summary.ex +++ b/lib/telemetry_metrics/summary.ex @@ -22,8 +22,8 @@ defmodule Telemetry.Metrics.Summary do event_name: :telemetry.event_name(), measurement: Metrics.measurement(), tags: Metrics.tags(), - tag_values: (:telemetry.event_metadata() -> :telemetry.event_metadata()), - keep: (:telemetry.event_metadata() -> boolean()), + tag_values: Metrics.tag_values(), + keep: Metrics.keep(), description: Metrics.description(), unit: Metrics.unit(), reporter_options: Metrics.reporter_options() diff --git a/test/telemetry_metrics_test.exs b/test/telemetry_metrics_test.exs index 199ff86..b2a1359 100644 --- a/test/telemetry_metrics_test.exs +++ b/test/telemetry_metrics_test.exs @@ -146,28 +146,31 @@ defmodule Telemetry.MetricsTest do keep_metric = apply(Metrics, unquote(metric_type), [ "my.repo.query", - [ - keep: &match?(%{repo: :my_app_read_only_repo}, &1) - ] + [keep: &match?(%{repo: :my_app_read_only_repo}, &1)] ]) drop_metric = apply(Metrics, unquote(metric_type), [ "my.repo.query", - [ - drop: &match?(%{repo: :my_app_read_only_repo}, &1) - ] + [drop: &match?(%{repo: :my_app_read_only_repo}, &1)] ]) - keep_filter_fun = keep_metric.keep + assert keep_metric.keep.(%{repo: :my_app_read_only_repo}) + refute keep_metric.keep.(%{repo: :my_app_repo}) - assert keep_filter_fun.(%{repo: :my_app_read_only_repo}) - refute keep_filter_fun.(%{repo: :my_app_repo}) + refute drop_metric.keep.(%{repo: :my_app_read_only_repo}) + assert drop_metric.keep.(%{repo: :my_app_repo}) + end - drop_filter_fun = drop_metric.keep + test "using event filter that evaluates both metadata and measurement" do + metric = + apply(Metrics, unquote(metric_type), [ + "my.repo.query", + [keep: &(match?(%{repo: :my_app_read_only_repo}, &1) and &2 > 100)] + ]) - refute drop_filter_fun.(%{repo: :my_app_read_only_repo}) - assert drop_filter_fun.(%{repo: :my_app_repo}) + assert metric.keep.(%{repo: :my_app_read_only_repo}, 200) + refute metric.keep.(%{repo: :my_app_read_only_repo}, 50) end test "setting both keep and drop options raises" do @@ -314,7 +317,7 @@ defmodule Telemetry.MetricsTest do end end - test "raises when event filter is not a function with an arity of 2" do + test "raises when event filter is not a function with an arity of 1 or 2" do Enum.each([keep: fn -> true end, drop: fn -> true end], fn filter -> assert_raise ArgumentError, fn -> apply(Metrics, unquote(metric_type), [