dogwatch 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|