Current section

Files

Jump to
prometheus_ecto lib prometheus_ecto_instrumenter.ex
Raw

lib/prometheus_ecto_instrumenter.ex

defmodule Prometheus.EctoInstrumenter do
use Prometheus.Config, [stages: [:queue, :query, :decode],
labels: [:result],
query_duration_buckets: [10, 100, 1_000, 10_000, 100_000, 300_000,
500_000, 750_000, 1_000_000, 1_500_000,
2_000_000, 3_000_000],
registry: :default]
use Prometheus.Metric
def setup do
labels = Config.labels
stages = Config.stages
for stage <- stages do
Histogram.declare([name: stage_metric_name(stage),
help: stage_metric_help(stage),
labels: labels,
buckets: Config.query_duration_buckets,
registry: Config.registry])
end
Histogram.declare([name: :ecto_query_duration_microseconds,
help: "Total Ecto query time",
labels: labels,
buckets: Config.query_duration_buckets,
registry: Config.registry])
end
def log(entry) do
labels = construct_labels(Config.labels, entry)
stages = Config.stages
if stages do
for stage <- stages do
value = stage_value(stage, entry)
if value != nil do
Histogram.observe([registry: Config.registry,
name: stage_metric_name(stage),
labels: labels], microseconds_time(value))
end
end
end
Histogram.observe([registry: Config.registry,
name: :ecto_query_duration_microseconds,
labels: labels], total_value(entry))
entry
end
defp construct_labels(labels, entry) do
for label <- labels, do: label_value(label, entry)
end
defp microseconds_time(time) do
System.convert_time_unit(time, :native, :micro_seconds)
end
defp label_value(:result, entry) do
{result, _} = entry.result
result
end
defp label_value({label, fun}, entry) when is_function(fun, 2), do: fun.(label, entry)
defp label_value(fun, entry) when is_function(fun, 1), do: fun.(entry)
defp stage_metric_name(:queue), do: :ecto_queue_duration_microseconds
defp stage_metric_name(:query), do: :ecto_db_query_duration_microseconds
defp stage_metric_name(:decode), do: :ecto_decode_duration_microseconds
defp stage_metric_help(:queue), do: "The time spent to check the connection out in microseconds."
defp stage_metric_help(:query), do: "The time spent executing the DB query in microseconds."
defp stage_metric_help(:decode), do: "The time spent decoding the result in microseconds."
defp stage_value(:queue, entry) do
entry.queue_time
end
defp stage_value(:query, entry) do
entry.query_time
end
defp stage_value(:decode, entry) do
entry.decode_time
end
def total_value(entry) do
zero_if_nil(entry.queue_time) +
zero_if_nil(entry.query_time) +
zero_if_nil(entry.decode_time)
end
defp zero_if_nil(value) do
if value == nil do
0
else
value
end
end
end