dogwatch 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/dogwatch +3 -1
- data/dogwatch.gemspec +1 -1
- data/example/Dogfile +20 -0
- data/lib/dogwatch.rb +3 -0
- data/lib/dogwatch/dogfile.rb +3 -2
- data/lib/dogwatch/model/client.rb +15 -3
- data/lib/dogwatch/model/config.rb +4 -1
- data/lib/dogwatch/model/mixin/colorize.rb +3 -0
- data/lib/dogwatch/model/monitor.rb +36 -5
- data/lib/dogwatch/model/options.rb +1 -0
- data/lib/dogwatch/model/response.rb +37 -8
- data/lib/dogwatch/monitor.rb +9 -7
- data/test/dogwatch/test_client.rb +8 -8
- data/test/dogwatch/test_monitor_model.rb +9 -2
- data/test/dogwatch/test_response.rb +5 -4
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 224be9842797fe4c2fc9c0cf3d88a9972759d54f
|
|
4
|
+
data.tar.gz: 5b14f7af6a5a64146640832cf53aa16fe350d0bc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f98c42c081bbf044495be9c26272e03699a74d581e9653cf5b6a21c8a3103c45d3d06b27b2c7faf8714b8033a928e5bdee2bffa8c95cb7b14e82ba452b6981d8
|
|
7
|
+
data.tar.gz: 026bf75a19af2a701511e8d7222dc176bf856fc4bac7ddee1cda6458eb09de0a46ea357836749a0cc015e054a0a3a84ef0438e03aeb7d12fdf069e6378c379ae
|
data/bin/dogwatch
CHANGED
|
@@ -10,6 +10,7 @@ module DogWatch
|
|
|
10
10
|
class_option :dogfile, :type => :string, :default => 'Dogfile'
|
|
11
11
|
class_option :api_key, :type => :string, :default => nil
|
|
12
12
|
class_option :app_key, :type => :string, :default => nil
|
|
13
|
+
class_option :timeout, :type => :numeric, :default => 5
|
|
13
14
|
def initialize(*args)
|
|
14
15
|
super
|
|
15
16
|
@cwd = Dir.getwd
|
|
@@ -19,7 +20,8 @@ module DogWatch
|
|
|
19
20
|
desc 'create', 'Create a monitor from a Dogfile'
|
|
20
21
|
def create
|
|
21
22
|
@dogfile.configure(File.absolute_path(options['dogfile'], @cwd),
|
|
22
|
-
options['api_key'], options['app_key']
|
|
23
|
+
options['api_key'], options['app_key'],
|
|
24
|
+
options['timeout'])
|
|
23
25
|
@dogfile.create { |c| say_status(*c.to_thor) }
|
|
24
26
|
end
|
|
25
27
|
end
|
data/dogwatch.gemspec
CHANGED
data/example/Dogfile
CHANGED
|
@@ -4,6 +4,26 @@
|
|
|
4
4
|
#
|
|
5
5
|
DogWatch.monitor do
|
|
6
6
|
monitor 'test_alert' do
|
|
7
|
+
type :metric_alert
|
|
8
|
+
query 'avg(last_1dm):avg:system.cpu.user{region:us-east-1} > 20'
|
|
9
|
+
message 'A message to include with notifications for this monitor.'\
|
|
10
|
+
'Email notifications can be sent to specific users by '\
|
|
11
|
+
'using the same \'@username\' notation as events.'
|
|
12
|
+
|
|
13
|
+
tags %w(A list of tags to associate with your monitor)
|
|
14
|
+
|
|
15
|
+
options do
|
|
16
|
+
silenced '*': nil
|
|
17
|
+
notify_no_data false
|
|
18
|
+
no_data_timeframe 3
|
|
19
|
+
timeout_h 99
|
|
20
|
+
renotify_interval 60
|
|
21
|
+
escalation_message 'oh snap'
|
|
22
|
+
include_tags true
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
monitor 'test_alert2' do
|
|
7
27
|
type :metric_alert
|
|
8
28
|
query 'avg(last_1m):avg:system.cpu.user{region:us-east-1} > 20'
|
|
9
29
|
message 'A message to include with notifications for this monitor.'\
|
data/lib/dogwatch.rb
CHANGED
data/lib/dogwatch/dogfile.rb
CHANGED
|
@@ -9,9 +9,10 @@ module DogWatch
|
|
|
9
9
|
# @param [String] dogfile
|
|
10
10
|
# @param [String|Object] api_key
|
|
11
11
|
# @param [String|Object] app_key
|
|
12
|
-
|
|
12
|
+
# @param [Integer] timeout
|
|
13
|
+
def configure(dogfile, api_key, app_key, timeout)
|
|
13
14
|
@dogfile = dogfile
|
|
14
|
-
@config = DogWatch::Model::Config.new(api_key, app_key)
|
|
15
|
+
@config = DogWatch::Model::Config.new(api_key, app_key, timeout)
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
# @param [Proc] block
|
|
@@ -15,11 +15,13 @@ module DogWatch
|
|
|
15
15
|
# @param [DogWatch::Model::Config] config
|
|
16
16
|
def initialize(config)
|
|
17
17
|
@config = config
|
|
18
|
-
@client = Dogapi::Client.new(@config.api_key, @config.app_key
|
|
18
|
+
@client = Dogapi::Client.new(@config.api_key, @config.app_key,
|
|
19
|
+
nil, nil, true, @config.timeout)
|
|
19
20
|
@all_monitors = all_monitors
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
# @param [DogWatch::Model::Monitor] monitor
|
|
24
|
+
# @return [DogWatch::Model::Response]
|
|
23
25
|
def execute(monitor)
|
|
24
26
|
if monitor_exists?(monitor.name)
|
|
25
27
|
update_monitor(monitor)
|
|
@@ -37,7 +39,7 @@ module DogWatch
|
|
|
37
39
|
monitor.attributes.query,
|
|
38
40
|
options)
|
|
39
41
|
updated = %w(200 202).include?(response[0])
|
|
40
|
-
|
|
42
|
+
DogWatch::Model::Response.new(response, options[:name], updated)
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
# @param [DogWatch::Model::Monitor] monitor
|
|
@@ -47,7 +49,17 @@ module DogWatch
|
|
|
47
49
|
response = @client.monitor(monitor.attributes.type,
|
|
48
50
|
monitor.attributes.query,
|
|
49
51
|
options)
|
|
50
|
-
|
|
52
|
+
DogWatch::Model::Response.new(response, options[:name])
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @param [Dogwatch::Model::Monitor] monitor
|
|
56
|
+
# @return [Dogwatch::Model::Response]
|
|
57
|
+
def validate(monitor)
|
|
58
|
+
validation = monitor.validate
|
|
59
|
+
return validation if validation.status == :error
|
|
60
|
+
|
|
61
|
+
# If no validation errors return a valid Response
|
|
62
|
+
DogWatch::Model::Response.new(['200', {}], 'valid')
|
|
51
63
|
end
|
|
52
64
|
|
|
53
65
|
private
|
|
@@ -9,12 +9,15 @@ module DogWatch
|
|
|
9
9
|
class Config
|
|
10
10
|
attr_accessor :api_key
|
|
11
11
|
attr_accessor :app_key
|
|
12
|
+
attr_accessor :timeout
|
|
12
13
|
|
|
13
14
|
# @param [String] api_key
|
|
14
15
|
# @param [String] app_key
|
|
15
|
-
|
|
16
|
+
# @param [Integer] timeout
|
|
17
|
+
def initialize(api_key = nil, app_key = nil, timeout = 5)
|
|
16
18
|
@api_key = api_key unless api_key.nil?
|
|
17
19
|
@app_key = app_key unless app_key.nil?
|
|
20
|
+
@timeout = timeout
|
|
18
21
|
return unless app_key.nil? || api_key.nil?
|
|
19
22
|
|
|
20
23
|
from_file
|
|
@@ -5,6 +5,9 @@ module DogWatch
|
|
|
5
5
|
# Provides a colorize() mixin that handles shell output coloring
|
|
6
6
|
##
|
|
7
7
|
module Colorize
|
|
8
|
+
# @param [Symbol] param
|
|
9
|
+
# @param [Hash] options
|
|
10
|
+
# @return [Symbol]
|
|
8
11
|
def colorize(param, options = {})
|
|
9
12
|
define_method(:color) do
|
|
10
13
|
case instance_variable_get("@#{ param }")
|
|
@@ -56,13 +56,44 @@ module DogWatch
|
|
|
56
56
|
@attributes.options = opts.render
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
# @return [
|
|
59
|
+
# @return [DogWatch::Model::Response]
|
|
60
60
|
def validate
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
@attributes.query.nil? || @attributes.query.empty?
|
|
61
|
+
return DogWatch::Model::Response.new(invalid_type_response, 'invalid') \
|
|
62
|
+
unless TYPE_MAP.key?(@monitor_type)
|
|
64
63
|
|
|
65
|
-
|
|
64
|
+
errors = []
|
|
65
|
+
errors.push('Missing monitor type') if missing_type?
|
|
66
|
+
errors.push('Missing monitor query') if missing_query?
|
|
67
|
+
|
|
68
|
+
if errors.empty?
|
|
69
|
+
DogWatch::Model::Response.new(['200', { :message => 'valid' }], 'valid')
|
|
70
|
+
else
|
|
71
|
+
DogWatch::Model::Response.new(['400', { 'errors' => errors }], 'invalid')
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def valid_types
|
|
78
|
+
TYPE_MAP.keys.map { |k| ":#{k}" }.join(', ')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def missing_type?
|
|
82
|
+
@attributes.type.nil? || @attributes.type.empty?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def missing_query?
|
|
86
|
+
@attributes.query.nil? || @attributes.query.empty?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def invalid_type_response
|
|
90
|
+
[
|
|
91
|
+
'400',
|
|
92
|
+
{ 'errors' => [
|
|
93
|
+
"Monitor type '#{@monitor_type}' is not valid. " \
|
|
94
|
+
"Valid monitor types are: #{valid_types}"
|
|
95
|
+
] }
|
|
96
|
+
]
|
|
66
97
|
end
|
|
67
98
|
end
|
|
68
99
|
end
|
|
@@ -11,6 +11,7 @@ module DogWatch
|
|
|
11
11
|
ERROR = '400'.freeze
|
|
12
12
|
CREATED = '200'.freeze
|
|
13
13
|
ACCEPTED = '202'.freeze
|
|
14
|
+
|
|
14
15
|
colorize(:action,
|
|
15
16
|
:green => [:created, :accepted, :updated],
|
|
16
17
|
:yellow => [],
|
|
@@ -18,11 +19,21 @@ module DogWatch
|
|
|
18
19
|
|
|
19
20
|
attr_accessor :response
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
# @param [Array] response
|
|
23
|
+
# @param [String] name
|
|
24
|
+
# @param [Boolean] updated
|
|
25
|
+
# @return [DogWatch::Model::Response]
|
|
26
|
+
def initialize(response, name, updated = false)
|
|
22
27
|
@response = response
|
|
23
28
|
@updated = updated
|
|
29
|
+
@name = if response[1]['name'].nil?
|
|
30
|
+
name
|
|
31
|
+
else
|
|
32
|
+
response[1]['name']
|
|
33
|
+
end
|
|
24
34
|
end
|
|
25
35
|
|
|
36
|
+
# @return [Symbol]
|
|
26
37
|
def status
|
|
27
38
|
return :updated if @updated == true
|
|
28
39
|
return :created if created?
|
|
@@ -30,13 +41,12 @@ module DogWatch
|
|
|
30
41
|
return :accepted if accepted?
|
|
31
42
|
end
|
|
32
43
|
|
|
44
|
+
# @return [String]
|
|
33
45
|
def message
|
|
34
|
-
|
|
35
|
-
return attrs['errors'] if attrs.key?('errors')
|
|
36
|
-
"#{status.to_s.capitalize} monitor #{attrs['name']}"\
|
|
37
|
-
" with message #{attrs['message']}"
|
|
46
|
+
send(status, @response[1])
|
|
38
47
|
end
|
|
39
48
|
|
|
49
|
+
# @return [Array]
|
|
40
50
|
def to_thor
|
|
41
51
|
action = status
|
|
42
52
|
text = message
|
|
@@ -45,16 +55,35 @@ module DogWatch
|
|
|
45
55
|
|
|
46
56
|
private
|
|
47
57
|
|
|
58
|
+
def error(attrs)
|
|
59
|
+
err = attrs['errors'].join(', ')
|
|
60
|
+
"The following errors occurred when creating monitor #{@name}: #{err}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def created(attrs)
|
|
64
|
+
"Created monitor #{@name} with message #{attrs['message']}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def updated(attrs)
|
|
68
|
+
# TODO: Use some kind of statefile to determine diffs between
|
|
69
|
+
# previously saved model and new version
|
|
70
|
+
"Updated monitor #{@name} with message #{attrs['message']}"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def accepted(attrs)
|
|
74
|
+
"Accepted monitor #{@name} with message #{attrs['message']}"
|
|
75
|
+
end
|
|
76
|
+
|
|
48
77
|
def accepted?
|
|
49
|
-
@response[0] == ACCEPTED
|
|
78
|
+
@response[0] == ACCEPTED
|
|
50
79
|
end
|
|
51
80
|
|
|
52
81
|
def created?
|
|
53
|
-
@response[0] == CREATED
|
|
82
|
+
@response[0] == CREATED
|
|
54
83
|
end
|
|
55
84
|
|
|
56
85
|
def failed?
|
|
57
|
-
@response[0] == ERROR
|
|
86
|
+
@response[0] == ERROR
|
|
58
87
|
end
|
|
59
88
|
end
|
|
60
89
|
end
|
data/lib/dogwatch/monitor.rb
CHANGED
|
@@ -32,20 +32,22 @@ module DogWatch
|
|
|
32
32
|
# @return [Array]
|
|
33
33
|
def get
|
|
34
34
|
@responses = @monitors.map do |m|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
validate = @client.validate(m)
|
|
36
|
+
if validate.status == :error
|
|
37
|
+
validate
|
|
37
38
|
else
|
|
38
|
-
|
|
39
|
-
# was never sent because the type or query wasn't supplied.
|
|
40
|
-
res = ['400', { 'errors' => ['The DogWatch monitor is invalid.'] }]
|
|
41
|
-
DogWatch::Model::Response.new(res)
|
|
39
|
+
@client.execute(m)
|
|
42
40
|
end
|
|
43
41
|
end
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
# @return [DogWatch::Model::Client]
|
|
47
45
|
def client(client = nil)
|
|
48
|
-
@client = client.nil?
|
|
46
|
+
@client = if client.nil?
|
|
47
|
+
DogWatch::Model::Client.new(@config)
|
|
48
|
+
else
|
|
49
|
+
client
|
|
50
|
+
end
|
|
49
51
|
end
|
|
50
52
|
end
|
|
51
53
|
end
|
|
@@ -8,20 +8,20 @@ require 'json'
|
|
|
8
8
|
class TestClient < Minitest::Test
|
|
9
9
|
TEST_RESPONSE = [
|
|
10
10
|
'200',
|
|
11
|
-
|
|
11
|
+
{
|
|
12
12
|
name: 'test monitor',
|
|
13
13
|
type: 'metric alert',
|
|
14
14
|
query: 'test query'
|
|
15
|
-
|
|
15
|
+
}
|
|
16
16
|
].freeze
|
|
17
17
|
|
|
18
18
|
UPDATED_RESPONSE = [
|
|
19
19
|
'200',
|
|
20
|
-
|
|
20
|
+
{
|
|
21
21
|
name: 'Monitor name',
|
|
22
22
|
type: :metric_alert,
|
|
23
23
|
query: 'scheduled maintenance query'
|
|
24
|
-
|
|
24
|
+
}
|
|
25
25
|
].freeze
|
|
26
26
|
|
|
27
27
|
def setup
|
|
@@ -48,8 +48,8 @@ class TestClient < Minitest::Test
|
|
|
48
48
|
new_monitor.query('test query')
|
|
49
49
|
|
|
50
50
|
@client.client.stub :monitor, TEST_RESPONSE do
|
|
51
|
-
@client.execute(new_monitor)
|
|
52
|
-
assert_equal
|
|
51
|
+
response = @client.execute(new_monitor)
|
|
52
|
+
assert_equal response.status, :created
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
@@ -59,8 +59,8 @@ class TestClient < Minitest::Test
|
|
|
59
59
|
update_monitor.query('scheduled maintenance query')
|
|
60
60
|
|
|
61
61
|
@client.client.stub :update_monitor, UPDATED_RESPONSE do
|
|
62
|
-
@client.execute(update_monitor)
|
|
63
|
-
assert_equal
|
|
62
|
+
response = @client.execute(update_monitor)
|
|
63
|
+
assert_equal response.status, :updated
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -45,9 +45,16 @@ class TestMonitorModel < Minitest::Test
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def test_validate
|
|
48
|
-
|
|
48
|
+
validation = @monitor.validate
|
|
49
|
+
assert_kind_of DogWatch::Model::Response, validation
|
|
50
|
+
assert_equal :created, validation.status
|
|
49
51
|
|
|
50
52
|
@monitor.attributes.query = nil
|
|
51
|
-
|
|
53
|
+
|
|
54
|
+
failed_validation = @monitor.validate
|
|
55
|
+
assert_kind_of DogWatch::Model::Response, failed_validation
|
|
56
|
+
assert_equal :error, failed_validation.status
|
|
57
|
+
assert_equal 'The following errors occurred when creating monitor ' \
|
|
58
|
+
'invalid: Missing monitor query', failed_validation.message
|
|
52
59
|
end
|
|
53
60
|
end
|
|
@@ -3,9 +3,9 @@ require_relative '../../lib/dogwatch/model/response'
|
|
|
3
3
|
|
|
4
4
|
class TestResponse < MiniTest::Test
|
|
5
5
|
def setup
|
|
6
|
-
@error_res = DogWatch::Model::Response.new(ERROR_RES)
|
|
7
|
-
@valid_res = DogWatch::Model::Response.new(VALID_RES)
|
|
8
|
-
@accepted_res = DogWatch::Model::Response.new(ACCEPTED_RES)
|
|
6
|
+
@error_res = DogWatch::Model::Response.new(ERROR_RES, 'error')
|
|
7
|
+
@valid_res = DogWatch::Model::Response.new(VALID_RES, 'foobar')
|
|
8
|
+
@accepted_res = DogWatch::Model::Response.new(ACCEPTED_RES, 'foobar')
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def test_status_is_error
|
|
@@ -17,7 +17,8 @@ class TestResponse < MiniTest::Test
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def test_status_message
|
|
20
|
-
assert_equal
|
|
20
|
+
assert_equal 'The following errors occurred when creating monitor error: ' \
|
|
21
|
+
"The value provided for parameter 'query' is invalid", \
|
|
21
22
|
@error_res.message
|
|
22
23
|
end
|
|
23
24
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dogwatch
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Greene
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-05-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dogapi
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1.
|
|
19
|
+
version: '1.27'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1.
|
|
26
|
+
version: '1.27'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: thor
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|