aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkballou <kballou@devnulllabs.io>2016-03-22 15:15:56 -0600
committerkballou <kballou@devnulllabs.io>2016-03-22 16:40:21 -0600
commitcdd1d2aff78b06fa5083d74bd38cbfc3301c48f2 (patch)
treec58dda5015359661fe5ab02d0d7e1f0fe18cbe74
parent03a7e6b96d22ead5eee26a37da90fcca59e8135b (diff)
downloadex_prometheus_io-cdd1d2aff78b06fa5083d74bd38cbfc3301c48f2.tar.gz
ex_prometheus_io-cdd1d2aff78b06fa5083d74bd38cbfc3301c48f2.tar.xz
Refactor query module
Break-up processing bits to add tests
-rw-r--r--lib/ex_prometheus_io.ex12
-rw-r--r--lib/ex_prometheus_io/query.ex60
-rw-r--r--test/ex_prometheus_io_query_test.exs50
3 files changed, 95 insertions, 27 deletions
diff --git a/lib/ex_prometheus_io.ex b/lib/ex_prometheus_io.ex
index cac39a5..dd47bee 100644
--- a/lib/ex_prometheus_io.ex
+++ b/lib/ex_prometheus_io.ex
@@ -7,25 +7,25 @@ defmodule ExPrometheusIo do
def query(query, _opts \\ []) do
query_opts = [query]
- spawn_query(:fetch_query, query_opts)
+ spawn_query(:query, query_opts)
end
def range(query, start_ts, end_ts, step, _opts \\ []) do
query_opts = [query, start_ts, end_ts, step]
- spawn_query(:fetch_range, query_opts)
+ spawn_query(:range, query_opts)
end
def series(matches, _opts \\ []) do
- spawn_query(:fetch_series, [matches])
+ spawn_query(:series, [matches])
end
- defp spawn_query(fetch, query_opts, _opts \\ []) do
+ defp spawn_query(query, query_opts, _opts \\ []) do
query_ref = make_ref()
- query_opts = query_opts ++ [query_ref, self()]
+ query_opts = [query | query_opts] ++ [query_ref, self()]
{:ok, pid} = Task.Supervisor.start_child(
ExPrometheusIo.QuerySupervisor,
ExPrometheusIo.Query,
- fetch,
+ :process,
query_opts)
{pid, query_ref}
end
diff --git a/lib/ex_prometheus_io/query.ex b/lib/ex_prometheus_io/query.ex
index 2bba7bd..140d0a9 100644
--- a/lib/ex_prometheus_io/query.ex
+++ b/lib/ex_prometheus_io/query.ex
@@ -1,41 +1,59 @@
defmodule ExPrometheusIo.Query do
- def fetch_query(query_str, query_ref, owner) do
- "query=#{query_str}" <> "&time=#{:os.system_time(:seconds)}"
- |> fetch_json("query")
+ def process(:query, query, query_ref, owner) do
+ build_url(:query, query)
+ |> fetch_json()
|> Poison.decode
|> send_results(query_ref, owner)
end
- def fetch_range(query_str, start_ts, end_ts, step, query_ref, owner) do
- "query=#{query_str}"
- <> "&start=#{start_ts}"
- <> "&end=#{end_ts}"
- <> "&step=#{step}"
- |> fetch_json("query_range")
+ def process(:range, query, start_ts, end_ts, step, query_ref, owner) do
+ build_url(:range, {query, start_ts, end_ts, step})
+ |> fetch_json()
|> Poison.decode
|> send_results(query_ref, owner)
end
- def fetch_series(matches, query_ref, owner) do
- matches
- |> Enum.map(fn(match) -> "match[]=#{match}" end)
- |> Enum.join("&")
- |> fetch_json("series")
+ def process(:series, matches, query_ref, owner) do
+ build_url(:series, matches)
+ |> fetch_json()
|> Poison.decode
|> send_results(query_ref, owner)
end
- defp fetch_json(query_str, query_type) do
- {:ok, {_, _, body}} = :httpc.request(
- "http://"
- <> prometheus_host
- <> "/api/v1/#{query_type}?"
- <> query_str
- |> String.to_char_list())
+ defp fetch_json(uri) do
+ {:ok, {_, _, body}} = :httpc.request(uri |> String.to_char_list())
body
end
+ def endpoint(:query), do: build_endpoint("query")
+ def endpoint(:range), do: build_endpoint("query_range")
+ def endpoint(:series), do: build_endpoint("series")
+ defp build_endpoint(endpoint) do
+ "http://" <> prometheus_host <> "/api/v1/#{endpoint}"
+ end
+ def build_url(query, opts) when query in [:query, :range, :series] do
+ endpoint(query) <> "?" <> query_params(query, opts)
+ end
+
+ def query_params(:query, query_parameter) do
+ query_time = :os.system_time(:seconds)
+ "query=#{query_parameter}&time=#{query_time}"
+ end
+
+ def query_params(:range, {topic, start_ts, end_ts, step}) do
+ "query=#{topic}"
+ <> "&start=#{start_ts}"
+ <> "&end=#{end_ts}"
+ <> "&step=#{step}"
+ end
+
+ def query_params(:series, matches) when is_list(matches) do
+ matches
+ |> Enum.map(fn(match) -> "match[]=#{match}" end)
+ |> Enum.join("&")
+ end
+
defp send_results({:error, :invalid} = results, query_ref, owner) do
send(owner, {:prometheus_results, query_ref, results})
end
diff --git a/test/ex_prometheus_io_query_test.exs b/test/ex_prometheus_io_query_test.exs
new file mode 100644
index 0000000..6e480a9
--- /dev/null
+++ b/test/ex_prometheus_io_query_test.exs
@@ -0,0 +1,50 @@
+defmodule ExPrometheusIo.QueryTest do
+ use ExUnit.Case
+
+ import ExPrometheusIo.Query, only: [query_params: 2,
+ endpoint: 1,
+ build_url: 2]
+
+ test "query_params builds proper query string" do
+ curr_time = :os.system_time(:seconds)
+ assert "query=up&time=#{curr_time}" == query_params(:query, "up")
+ end
+
+ test "query_params builds correct range query" do
+ curr_time = :os.system_time(:seconds)
+ assert "query=up&start=#{curr_time-5}&end=#{curr_time}&step=1" ==
+ query_params(:range, {"up", curr_time - 5, curr_time, 1})
+ end
+
+ test "query_params builds correct series query" do
+ assert "match[]=up" == query_params(:series, ["up"])
+ end
+
+ test "query endpoint" do
+ assert "http://#{prom_host}/api/v1/query" == endpoint(:query)
+ end
+
+ test "range endpoint" do
+ assert "http://#{prom_host}/api/v1/query_range" == endpoint(:range)
+ end
+
+ test "series endpoint" do
+ assert "http://#{prom_host}/api/v1/series" == endpoint(:series)
+ end
+
+ test "build url" do
+ base_url = "http://#{prom_host}/api/v1/"
+ cur_time = :os.system_time(:seconds)
+ assert base_url <> "query?query=up&time=#{cur_time}"
+ == build_url(:query, "up")
+ assert base_url <> "query_range?query=up"
+ <> "&start=#{cur_time-5}"
+ <> "&end=#{cur_time}"
+ <> "&step=1"
+ == build_url(:range, {"up", cur_time - 5, cur_time, 1})
+ assert base_url <> "series?match[]=up" == build_url(:series, ["up"])
+ end
+
+ defp prom_host, do: Application.fetch_env!(:ex_prometheus_io, :hostname)
+
+end