diff options
-rw-r--r-- | lib/exdatadog/metrics.ex | 34 | ||||
-rw-r--r-- | lib/exdatadog/monitors.ex | 23 | ||||
-rw-r--r-- | lib/exdatadog/search.ex | 23 | ||||
-rw-r--r-- | test/exdatadog/metrics_test.exs | 85 | ||||
-rw-r--r-- | test/exdatadog/monitors_test.exs | 81 | ||||
-rw-r--r-- | test/exdatadog/search_test.exs | 51 | ||||
-rw-r--r-- | test/fixture/vcr_cassettes/metrics/metrics.json | 16 | ||||
-rw-r--r-- | test/fixture/vcr_cassettes/metrics/post_series.json | 16 | ||||
-rw-r--r-- | test/fixture/vcr_cassettes/metrics/query.json | 16 | ||||
-rw-r--r-- | test/fixture/vcr_cassettes/monitors/details.json | 16 | ||||
-rw-r--r-- | test/fixture/vcr_cassettes/monitors/details_with_group_states.json | 19 | ||||
-rw-r--r-- | test/fixture/vcr_cassettes/search/faceted.json | 16 | ||||
-rw-r--r-- | test/fixture/vcr_cassettes/search/unfaceted.json | 16 |
13 files changed, 412 insertions, 0 deletions
diff --git a/lib/exdatadog/metrics.ex b/lib/exdatadog/metrics.ex new file mode 100644 index 0000000..26c238e --- /dev/null +++ b/lib/exdatadog/metrics.ex @@ -0,0 +1,34 @@ +defmodule Exdatadog.Metrics do + @moduledoc """ + Metrics functions for DataDog + """ + import Exdatadog + + @doc """ + Return active metrics between from given time to now + + Required parameter: `from`, seconds since unix epoch + """ + @spec metrics(integer, Exdatadog.Client.t) :: Exdatadog.response + def metrics(from, client) when is_integer(from) do + get("api/v1/metrics", client, from: from) + end + + @doc """ + Post time-series data to Datadog + """ + @spec post_series(map, Exdatadog.Client.t) :: Exdatadog.response + def post_series(series, client) when is_map(series) do + post("api/v1/series", client, series) + end + + @doc """ + Query Metrics for any time period + """ + @spec query(integer, integer, binary, Exdatadog.Client.t) :: + Exdatadog.response + def query(from, to, query, client) do + get("api/v1/query", client, [from: from, to: to, query: query]) + end + +end diff --git a/lib/exdatadog/monitors.ex b/lib/exdatadog/monitors.ex new file mode 100644 index 0000000..9d271be --- /dev/null +++ b/lib/exdatadog/monitors.ex @@ -0,0 +1,23 @@ +defmodule Exdatadog.Monitors do + @moduledoc """ + Module for interacting with Datadog Monitors + """ + + import Exdatadog + + @doc """ + Request the details of a monitor + """ + @spec details(integer, List.t, Exdatadog.Client.t) :: Exdatadog.response + def details(id, group_states \\ [], client) + def details(id, [], client) do + get("api/v1/monitor/#{id}", client) + end + def details(id, group_states, client) do + get("api/v1/monitor/#{id}", + client, + group_states: Enum.join(group_states, ",")) + end + + +end diff --git a/lib/exdatadog/search.ex b/lib/exdatadog/search.ex new file mode 100644 index 0000000..23e6fd6 --- /dev/null +++ b/lib/exdatadog/search.ex @@ -0,0 +1,23 @@ +defmodule Exdatadog.Search do + @moduledoc """ + Search for metrics or hosts in DataDog + """ + + import Exdatadog + + @doc """ + Search for entities in the last 24 hours in DataDog + + Available entities to search for are: + + * `hosts` + + * `metrics` + + """ + @spec search(binary, Exdatadog.Client.t) :: Exdatadog.response + def search(query, client) do + get("api/v1/search", client, [q: query]) + end + +end diff --git a/test/exdatadog/metrics_test.exs b/test/exdatadog/metrics_test.exs new file mode 100644 index 0000000..17f44b4 --- /dev/null +++ b/test/exdatadog/metrics_test.exs @@ -0,0 +1,85 @@ +defmodule Exdatadog.Metrics.Test do + @moduledoc """ + Provides testing for Exdatadog.Metrics + """ + use ExUnit.Case + use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney + + @cassette_dir "test/fixture/vcr_cassettes/metrics" + + alias Exdatadog.Client + import Exdatadog.Metrics + + @lint {Credo.Check.Design.AliasUsage, false} + setup_all do + ExVCR.Config.cassette_library_dir(@cassette_dir) + end + + test "can get list of active metrics" do + client = Client.new() + expected = {200, %{"metrics" => ["system.load.1", + "system.load.15", + "system.load.5", + "system.load.norm.1", + "system.load.norm.15", + "system.load.norm.5", + "system.mem.buffered", + "system.mem.cached", + "system.mem.committed", + "system.mem.free"], + "from" => 1_467_815_773} + } + use_cassette "metrics" do + assert metrics(1_467_815_773, client) == expected + end + end + + test "can post metrics" do + client = Client.new(%{api_key: "1234"}) + expected = {202, %{"status" => "ok"}} + post_body = %{"series" => [%{"metric" => "test_metric", + "points" => [[1_430_311_800_000, 20]], + "type" => "gauge", + "host" => "test.example.com", + "tags" => ["environment:test"]}] + } + use_cassette "post_series" do + assert post_series(post_body, client) == expected + end + end + + test "can query metrics" do + client = Client.new() + expected = {200, + %{"status" => "ok", + "res_type" => "time_series", + "series" => [%{"metric" =>"system.cpu.idle", + "attributes" => %{}, + "display_name" => "system.cpu.idle", + "unit" => nil, + "pointlist" => [[1_430_311_800_000, + 98.19375610351562], + [1_430_312_400_000, + 99.85856628417969]], + "end" => 1_430_312_999_000, + "interval" => 600, + "start" => 1_430_311_800_000, + "length" => 2, + "aggr" => nil, + "scope" => "host:vagrant-ubuntu-trusty-64", + "expression" => "system.cpu.idle{host:vagrant-ubuntu-trusty-64}"}], + "from_date" => 1_430_226_140_000, + "group_by" => ["host"], + "to_date" => 1_430_312_540_000, + "query" => "system.cpu.idle{*}by{host}", + "message" => ""} + } + use_cassette "query" do + assert query(1_430_311_800_000, + 1_430_312_999_000, + "system.cpu.idle{*}by{host}", + client) == expected + end + end + +end diff --git a/test/exdatadog/monitors_test.exs b/test/exdatadog/monitors_test.exs new file mode 100644 index 0000000..803ca57 --- /dev/null +++ b/test/exdatadog/monitors_test.exs @@ -0,0 +1,81 @@ +defmodule Exdatadog.Monitors.Test do + @moduledoc """ + Tests Exdatadog.Monitors + """ + use ExUnit.Case + use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney + + @cassette_dir "test/fixture/vcr_cassettes/monitors" + + alias Exdatadog.Client + import Exdatadog.Monitors + + doctest Exdatadog.Monitors + + @lint {Credo.Check.Design.AliasUsage, false} + setup_all do + ExVCR.Config.cassette_library_dir(@cassette_dir) + end + + test "can get montior details" do + client = Client.new() + expected = {200, + %{"created" => "2015-12-18T16:34:14.014039+00:00", + "id" => 91_879, + "message" => "We may need to add web hosts if this is consistently high.", + "modified" => "2015-12-18T16:34:14.014039+00:00", + "multi" => false, + "name" => "Bytes received on host0", + "options" => %{"notify_audit" => false, + "notify_no_data" => false, + "silenced" => %{}}, + "org_id" => 1499, + "query" => "avg(last_1h):sum:system.net.bytes_rcvd{host:host0} > 100", + "type" => "metric alert" + }} + + use_cassette "details" do + assert details(91_879, client) == expected + end + end + + test "can get monitor details with group_states" do + client = Client.new() + expected = {200, + %{"created" => "2015-12-18T16:34:14.014039+00:00", + "id" => 91_879, + "message" => "We may need to add web hosts if this is consistently high.", + "modified" => "2015-12-18T16:34:14.014039+00:00", + "multi" => false, + "name" => "Bytes received on host0", + "options" => %{"no_data_timeframe" => 20, + "notify_audit" => false, + "notify_no_data" => false, + "silenced" => %{}}, + "org_id" => 1499, + "query" => "avg(last_1h):sum:system.net.bytes_rcvd{host:host0} > 100", + "type" => "metric alert", + "state" => %{ + "groups" => %{ + "host:host0" => %{ + "last_nodata_ts" => nil, + "last_notified_ts" => 1_481_909_160, + "last_resolved_ts" => 1_481_908_200, + "last_triggered_ts" => 1_481_909_160, + "name" => "host:host0", + "status" => "Alert", + "triggering_value" => %{ + "from_ts" => 1_481_909_037, + "to_ts" => 1_481_909_097, + "value" => 1_000} + } + } + } + } + } + + use_cassette "details_with_group_states" do + assert details(91_879, ~w(alert warn), client) == expected + end + end +end diff --git a/test/exdatadog/search_test.exs b/test/exdatadog/search_test.exs new file mode 100644 index 0000000..979784f --- /dev/null +++ b/test/exdatadog/search_test.exs @@ -0,0 +1,51 @@ +defmodule Exdatadog.Search.Test do + @moduledoc """ + Tests Exdatadog.Search + """ + use ExUnit.Case + use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney + + @cassette_dir "test/fixture/vcr_cassettes/search" + + alias Exdatadog.Client + import Exdatadog.Search + + doctest Exdatadog.Search + + @lint {Credo.Check.Design.AliasUsage, false} + setup_all do + ExVCR.Config.cassette_library_dir(@cassette_dir) + end + + test "search with un-faceted query" do + client = Client.new() + expected = { + 200, + %{"results" => %{"metrics" => ["test.metric"], + "hosts" => ["test.another.example.com", + "test.example.com", + "test.host", + "test.metric.host", + "test.tag.host"]}} + } + use_cassette "unfaceted" do + assert search("test", client) == expected + end + end + + test "search with faceted query" do + client = Client.new() + expected = { + 200, + %{"results" => %{"hosts" => ["test.another.example.com", + "test.example.com", + "test.host", + "test.metric.host", + "test.tag.host"]}} + } + use_cassette "faceted" do + assert search("hosts:test", client) == expected + end + end + +end diff --git a/test/fixture/vcr_cassettes/metrics/metrics.json b/test/fixture/vcr_cassettes/metrics/metrics.json new file mode 100644 index 0000000..f66d8f4 --- /dev/null +++ b/test/fixture/vcr_cassettes/metrics/metrics.json @@ -0,0 +1,16 @@ +[ + { + "request": { + "body": "", + "method": "get", + "options": [], + "request_body": "", + "url": "https://app.datadoghq.com/api/v1/metrics?api_key=1234&application_key=abcd&from=1467815773" + }, + "response": { + "body": "{\"metrics\":[\"system.load.1\",\"system.load.15\",\"system.load.5\",\"system.load.norm.1\",\"system.load.norm.15\",\"system.load.norm.5\",\"system.mem.buffered\",\"system.mem.cached\",\"system.mem.committed\",\"system.mem.free\"],\"from\":1467815773}", + "status_code": 200, + "type": "ok" + } + } +] diff --git a/test/fixture/vcr_cassettes/metrics/post_series.json b/test/fixture/vcr_cassettes/metrics/post_series.json new file mode 100644 index 0000000..091e8f9 --- /dev/null +++ b/test/fixture/vcr_cassettes/metrics/post_series.json @@ -0,0 +1,16 @@ +[ + { + "request": { + "body": "{\"series\":[{\"type\":\"gauge\",\"tags\":[\"environment:test\"],\"points\":[[14303118000000,20]],\"metric\":\"test.metric\",\"host\":\"test.example.com\"}]}", + "method": "post", + "options": [], + "request_body": "", + "url": "https://app.datadoghq.com/api/v1/series?api_key=1234" + }, + "response": { + "body": "{\"status\":\"ok\"}", + "status_code": 202, + "type": "ok" + } + } +] diff --git a/test/fixture/vcr_cassettes/metrics/query.json b/test/fixture/vcr_cassettes/metrics/query.json new file mode 100644 index 0000000..69639a7 --- /dev/null +++ b/test/fixture/vcr_cassettes/metrics/query.json @@ -0,0 +1,16 @@ +[ + { + "request": { + "body": "", + "method": "get", + "options": [], + "request_body": "", + "url": "https://app.datadoghq.com/api/v1/query?api_key=1234&application_key=abcd&to=1430312999000from=1430226140000&query=system.cpu.idle{*}by{host}" + }, + "response": { + "body": "{\"status\":\"ok\",\"res_type\":\"time_series\",\"series\":[{\"metric\":\"system.cpu.idle\",\"attributes\":{},\"display_name\":\"system.cpu.idle\",\"unit\":null,\"pointlist\":[[1430311800000,98.19375610351562],[1430312400000,99.85856628417969]],\"end\":1430312999000,\"interval\":600,\"start\":1430311800000,\"length\":2,\"aggr\":null,\"scope\":\"host:vagrant-ubuntu-trusty-64\",\"expression\":\"system.cpu.idle{host:vagrant-ubuntu-trusty-64}\"}],\"from_date\":1430226140000,\"group_by\":[\"host\"],\"to_date\":1430312540000,\"query\":\"system.cpu.idle{*}by{host}\",\"message\":\"\"}", + "status_code": 200, + "type": "ok" + } + } +] diff --git a/test/fixture/vcr_cassettes/monitors/details.json b/test/fixture/vcr_cassettes/monitors/details.json new file mode 100644 index 0000000..cc77b1a --- /dev/null +++ b/test/fixture/vcr_cassettes/monitors/details.json @@ -0,0 +1,16 @@ +[ + { + "request": { + "body": "", + "method": "get", + "options": [], + "request_body": "", + "url": "https://app.datadoghq.com/api/v1/monitor/91879?api_key=1234&application_key=abcd" + }, + "response": { + "body": "{\"id\":91879,\"message\":\"We may need to add web hosts if this is consistently high.\",\"name\":\"Bytes received on host0\",\"options\":{\"notify_audit\":false,\"notify_no_data\":false,\"silenced\":{}},\"org_id\":1499,\"query\":\"avg(last_1h):sum:system.net.bytes_rcvd{host:host0} > 100\",\"type\":\"metric alert\",\"multi\":false,\"created\":\"2015-12-18T16:34:14.014039+00:00\",\"modified\":\"2015-12-18T16:34:14.014039+00:00\"}", + "status_code": 200, + "type": "ok" + } + } +] diff --git a/test/fixture/vcr_cassettes/monitors/details_with_group_states.json b/test/fixture/vcr_cassettes/monitors/details_with_group_states.json new file mode 100644 index 0000000..2de9ea9 --- /dev/null +++ b/test/fixture/vcr_cassettes/monitors/details_with_group_states.json @@ -0,0 +1,19 @@ +[ + { + "request": { + "body": "\"\"", + "headers": { + "user-agent": "exdatadog" + }, + "method": "get", + "options": [], + "request_body": "", + "url": "https://app.datadoghq.com/api/v1/monitor/91879?api_key=1234&application_key=abcd&group_states=alert%2Cwarn" + }, + "response": { + "body": "{\"id\":91879,\"message\":\"We may need to add web hosts if this is consistently high.\",\"name\":\"Bytes received on host0\",\"options\":{\"no_data_timeframe\":20,\"notify_audit\":false,\"notify_no_data\":false,\"silenced\":{}},\"org_id\":1499,\"query\":\"avg(last_1h):sum:system.net.bytes_rcvd{host:host0} > 100\",\"type\":\"metric alert\",\"multi\":false,\"created\":\"2015-12-18T16:34:14.014039+00:00\",\"modified\":\"2015-12-18T16:34:14.014039+00:00\",\"state\":{\"groups\":{\"host:host0\":{\"last_nodata_ts\":null,\"last_notified_ts\":1481909160,\"last_resolved_ts\":1481908200,\"last_triggered_ts\":1481909160,\"name\":\"host:host0\",\"status\":\"Alert\",\"triggering_value\":{\"from_ts\":1481909037,\"to_ts\":1481909097,\"value\":1000}}}}}", + "status_code": 200, + "type": "ok" + } + } +] diff --git a/test/fixture/vcr_cassettes/search/faceted.json b/test/fixture/vcr_cassettes/search/faceted.json new file mode 100644 index 0000000..3e74aaa --- /dev/null +++ b/test/fixture/vcr_cassettes/search/faceted.json @@ -0,0 +1,16 @@ +[ + { + "request": { + "body": "", + "method": "get", + "options": [], + "request_body": "", + "url": "https://app.datadoghq.com/api/v1/search?api_key=1234&application_key=abcd&q=test" + }, + "response": { + "body": "{\"results\":{\"hosts\":[\"test.another.example.com\",\"test.example.com\",\"test.host\",\"test.metric.host\",\"test.tag.host\"]}}", + "status_code": 200, + "type": "ok" + } + } +] diff --git a/test/fixture/vcr_cassettes/search/unfaceted.json b/test/fixture/vcr_cassettes/search/unfaceted.json new file mode 100644 index 0000000..efcadf7 --- /dev/null +++ b/test/fixture/vcr_cassettes/search/unfaceted.json @@ -0,0 +1,16 @@ +[ + { + "request": { + "body": "", + "method": "get", + "options": [], + "request_body": "", + "url": "https://app.datadoghq.com/api/v1/search?api_key=1234&application_key=abcd&q=test" + }, + "response": { + "body": "{\"results\":{\"hosts\":[\"test.another.example.com\",\"test.example.com\",\"test.host\",\"test.metric.host\",\"test.tag.host\"],\"metrics\":[\"test.metric\"]}}", + "status_code": 200, + "type": "ok" + } + } +] |