aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkballou <kballou@devnulllabs.io>2016-12-27 10:06:46 -0700
committerkballou <kballou@devnulllabs.io>2016-12-27 10:40:46 -0700
commit9752309f2f44804f8aa077086a732b3455a5d125 (patch)
treead33f807f3ef10ef6274e7cd56f104faf028e482
parent6e36a9c3fb482cc993a3fa6511c51cc19b59d5a2 (diff)
downloadexdatadog-wip.tar.gz
exdatadog-wip.tar.xz
WIP: Fleshout API implementationwip
-rw-r--r--lib/exdatadog/metrics.ex34
-rw-r--r--lib/exdatadog/monitors.ex23
-rw-r--r--lib/exdatadog/search.ex23
-rw-r--r--test/exdatadog/metrics_test.exs85
-rw-r--r--test/exdatadog/monitors_test.exs81
-rw-r--r--test/exdatadog/search_test.exs51
-rw-r--r--test/fixture/vcr_cassettes/metrics/metrics.json16
-rw-r--r--test/fixture/vcr_cassettes/metrics/post_series.json16
-rw-r--r--test/fixture/vcr_cassettes/metrics/query.json16
-rw-r--r--test/fixture/vcr_cassettes/monitors/details.json16
-rw-r--r--test/fixture/vcr_cassettes/monitors/details_with_group_states.json19
-rw-r--r--test/fixture/vcr_cassettes/search/faceted.json16
-rw-r--r--test/fixture/vcr_cassettes/search/unfaceted.json16
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"
+ }
+ }
+]