deckard 0.5.10 → 0.5.12
Sign up to get free protection for your applications and to get access to all the features.
- data/README +34 -1
- data/config/deckard-test.yml +3 -0
- data/config/deckard.yml +7 -0
- data/lib/deckard.rb +2 -0
- data/lib/deckard/chef.rb +31 -0
- data/lib/deckard/config.rb +14 -1
- data/lib/deckard/monitoring.rb +27 -5
- data/lib/deckard/stats.rb +24 -0
- metadata +6 -4
data/README
CHANGED
@@ -16,6 +16,8 @@ Features:
|
|
16
16
|
* Simple setup via cron
|
17
17
|
* Basic scheduling to silence alerts
|
18
18
|
* Adjustable delay before firing check content requests
|
19
|
+
* Basic Chef "tag" lookup support
|
20
|
+
* Alert stats database for trending and analysis
|
19
21
|
|
20
22
|
Usage:
|
21
23
|
|
@@ -90,4 +92,35 @@ HTTP content check format:
|
|
90
92
|
}
|
91
93
|
|
92
94
|
|
93
|
-
For all of these priority and schedule are optional fields in these documents, priority is 0, 1 and 2. 0 is log only, 1 is log and email and 2 is log, email and sms. The schedule is an array containing integers for the hours the alert should be silent. Check out the replication check definition above.
|
95
|
+
For all of these priority and schedule are optional fields in these documents, priority is 0, 1 and 2. 0 is log only, 1 is log and email and 2 is log, email and sms. The schedule is an array containing integers for the hours the alert should be silent. Check out the replication check definition above.
|
96
|
+
|
97
|
+
|
98
|
+
For Chef "tag" support you need to install a view in your chef database and configure the url to it in your Deckard config file.
|
99
|
+
|
100
|
+
function(doc) {
|
101
|
+
if (doc.chef_type != 'node') return;
|
102
|
+
|
103
|
+
emit(doc.automatic.ec2 ? doc.automatic.ec2.public_hostname : doc.automatic.fqdn, doc.normal.tags[0]);
|
104
|
+
}
|
105
|
+
|
106
|
+
|
107
|
+
Regarding alert stats, just create a stats database and puts it's name in the config file. When alerts happen you should begin to see documents get added. By itself it isn't all that helpful, analysis is the key. Here is a basic "counts" design document to get you started, it will give you stats about the different kinds of alerts you are having.
|
108
|
+
|
109
|
+
{
|
110
|
+
"_id": "_design/counts",
|
111
|
+
"language": "javascript",
|
112
|
+
"views": {
|
113
|
+
"by_type": {
|
114
|
+
"map": "function(doc) {\n emit(doc.type, 1);\n}",
|
115
|
+
"reduce": "_count"
|
116
|
+
},
|
117
|
+
"by_url": {
|
118
|
+
"map": "function(doc) {\n emit(doc.url, 1);\n}",
|
119
|
+
"reduce": "_count"
|
120
|
+
},
|
121
|
+
"by_error": {
|
122
|
+
"map": "function(doc) {\n emit(doc.error, 1);\n}",
|
123
|
+
"reduce": "_count"
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
data/config/deckard-test.yml
CHANGED
data/config/deckard.yml
CHANGED
data/lib/deckard.rb
CHANGED
data/lib/deckard/chef.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Deckard
|
2
|
+
class Chef
|
3
|
+
|
4
|
+
def self.get_node_info(url)
|
5
|
+
|
6
|
+
info = false
|
7
|
+
|
8
|
+
if Deckard::Config.chef_enabled
|
9
|
+
|
10
|
+
chef_url = Deckard::Config.chef_url
|
11
|
+
|
12
|
+
begin
|
13
|
+
chef_nodes_json = RestClient.get(chef_url)
|
14
|
+
chef_nodes = JSON.parse(chef_nodes_json)
|
15
|
+
|
16
|
+
chef_nodes["rows"].each do |row|
|
17
|
+
if row["key"] == URI.parse(url).host
|
18
|
+
info = row["value"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
rescue Exception => e
|
23
|
+
Deckard::Log.error("Could not get chef tag for alert on #{url} due to #{e}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
info
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/deckard/config.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
class Deckard
|
2
2
|
class Config
|
3
|
-
|
3
|
+
|
4
|
+
if ARGV[0]
|
5
|
+
monitor_config = YAML.load(File.open(ARGV[1]))
|
6
|
+
else
|
7
|
+
puts "No config file specified"
|
8
|
+
abort
|
9
|
+
end
|
10
|
+
|
4
11
|
extend Mixlib::Config
|
5
12
|
configure do |c|
|
6
13
|
c[:email_to] = monitor_config["defaults"]["email_to"]
|
@@ -31,6 +38,12 @@ class Deckard
|
|
31
38
|
|
32
39
|
c[:notifo_user] = monitor_config["notifo"]["user"]
|
33
40
|
c[:notifo_apikey] = monitor_config["notifo"]["apikey"]
|
41
|
+
|
42
|
+
c[:stats_db] = monitor_config["stats"]["db"]
|
43
|
+
|
44
|
+
c[:chef_url] = monitor_config["chef"]["url"]
|
45
|
+
c[:chef_enabled] = monitor_config["chef"]["enabled"]
|
46
|
+
|
34
47
|
end
|
35
48
|
end
|
36
49
|
end
|
data/lib/deckard/monitoring.rb
CHANGED
@@ -11,10 +11,20 @@ class Deckard
|
|
11
11
|
sleep(Deckard::Config.content_check_retry_interval)
|
12
12
|
retry if (retries += 1) < retry_count
|
13
13
|
if retries >= retry_count
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
node_info = Deckard::Chef.get_node_info(url)
|
16
|
+
|
17
|
+
if node_info
|
18
|
+
subject = "ALERT :: #{node_info} :: #{e}"
|
19
|
+
body = "#{Time.now} :: #{url}"
|
20
|
+
else
|
21
|
+
subject = "ALERT :: #{url} :: #{e}"
|
22
|
+
body = "#{Time.now} :: #{url} :: #{e}"
|
23
|
+
end
|
24
|
+
|
16
25
|
log = subject + " -- " + body
|
17
26
|
Deckard::Util.alert(priority, subject, body, log, schedule, url)
|
27
|
+
Deckard::Stats.alert(priority, e, url, "contentcheck")
|
18
28
|
check = false
|
19
29
|
end
|
20
30
|
else
|
@@ -22,10 +32,20 @@ class Deckard
|
|
22
32
|
if result.include?(content)
|
23
33
|
Deckard::Log.info("PASS :: Found text \"#{content}\" on #{url}")
|
24
34
|
else
|
25
|
-
|
26
|
-
|
35
|
+
|
36
|
+
node_info = Deckard::Chef.get_node_info(url)
|
37
|
+
|
38
|
+
if node_info
|
39
|
+
subject = "ALERT :: #{node_info} :: content missing"
|
40
|
+
body = "#{Time.now} :: Could not find text \"#{content}\" at #{url}"
|
41
|
+
else
|
42
|
+
subject = "ALERT :: #{url} :: content missing"
|
43
|
+
body = "#{Time.now} :: Could not find text \"#{content}\" at #{url}"
|
44
|
+
end
|
45
|
+
|
27
46
|
log = subject + " -- " + body
|
28
47
|
Deckard::Util.alert(priority, subject, body, log, schedule, url)
|
48
|
+
Deckard::Stats.alert(priority, "nocontent", url, "contentcheck")
|
29
49
|
check = false
|
30
50
|
end
|
31
51
|
end
|
@@ -49,6 +69,7 @@ class Deckard
|
|
49
69
|
body = "Master: #{master_url} => Slave: #{slave_url} : off by #{doc_count_diff}"
|
50
70
|
log = subject + " -- " + body
|
51
71
|
Deckard::Util.alert(priority, subject, body, log, schedule, master_url)
|
72
|
+
Deckard::Stats.alert(priority, "#{doc_count_diff}", url, "replication")
|
52
73
|
else
|
53
74
|
Deckard::Log.info("PASS :: Replication for #{name} is OK (#{doc_count_diff})")
|
54
75
|
end
|
@@ -64,7 +85,8 @@ class Deckard
|
|
64
85
|
body = "#{region} : #{elastic_ip} => #{primary_instance_id} / #{secondary_instance_id} attempting failover!"
|
65
86
|
log = subject + " " + body
|
66
87
|
Deckard::Util.alert(priority, subject, body, log, schedule, "http://#{elastic_ip}")
|
67
|
-
|
88
|
+
Deckard::Stats.alert(priority, "unknown", "http://#{elastic_ip}", "failover")
|
89
|
+
|
68
90
|
instance_id = Deckard::Ec2.get_association(region, elastic_ip)
|
69
91
|
|
70
92
|
if Deckard::Ec2.disassociate_address(region, elastic_ip)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Deckard
|
2
|
+
class Stats
|
3
|
+
|
4
|
+
def self.alert(priority, error, url, type)
|
5
|
+
db_name = Deckard::Config.stats_db
|
6
|
+
db_user = Deckard::Config.db_user
|
7
|
+
db_password = Deckard::Config.db_password
|
8
|
+
db_host = Deckard::Config.db_host
|
9
|
+
db_port = Deckard::Config.db_port
|
10
|
+
|
11
|
+
db_url = "http://#{db_user}:#{db_password}@#{db_host}:#{db_port}/#{db_name}"
|
12
|
+
|
13
|
+
alert_info = {"priority" => priority, "error" => error, "url" => url, "timestamp" => Time.now.utc.iso8601, "type" => type}
|
14
|
+
|
15
|
+
begin
|
16
|
+
RestClient.post("#{db_url}", alert_info.to_json, "Content-Type" => "application/json")
|
17
|
+
Deckard::Log.info("Added stats for alert on #{url}")
|
18
|
+
rescue Exception => e
|
19
|
+
Deckard::Log.error("Could not add stats for alert on #{url} due to #{e}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deckard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
9
|
+
- 12
|
10
|
+
version: 0.5.12
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- joe williams
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-08 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -128,10 +128,12 @@ extra_rdoc_files:
|
|
128
128
|
- README
|
129
129
|
files:
|
130
130
|
- bin/deckard
|
131
|
+
- lib/deckard/chef.rb
|
131
132
|
- lib/deckard/config.rb
|
132
133
|
- lib/deckard/ec2.rb
|
133
134
|
- lib/deckard/log.rb
|
134
135
|
- lib/deckard/monitoring.rb
|
136
|
+
- lib/deckard/stats.rb
|
135
137
|
- lib/deckard/util.rb
|
136
138
|
- lib/deckard.rb
|
137
139
|
- config/deckard-test.yml
|