riemann-tools 1.0.0 → 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/.github/dependabot.yml +11 -0
- data/.github/workflows/ci.yml +13 -0
- data/.github/workflows/codeql-analysis.yml +72 -0
- data/.rubocop.yml +32 -0
- data/CHANGELOG.md +31 -2
- data/README.markdown +8 -24
- data/Rakefile +4 -2
- data/SECURITY.md +42 -0
- data/bin/riemann-apache-status +92 -78
- data/bin/riemann-bench +54 -49
- data/bin/riemann-cloudant +44 -40
- data/bin/riemann-consul +82 -76
- data/bin/riemann-dir-files-count +53 -47
- data/bin/riemann-dir-space +53 -47
- data/bin/riemann-diskstats +78 -75
- data/bin/riemann-fd +68 -48
- data/bin/riemann-freeswitch +108 -103
- data/bin/riemann-haproxy +46 -40
- data/bin/riemann-health +4 -343
- data/bin/riemann-kvminstance +18 -13
- data/bin/riemann-memcached +35 -29
- data/bin/riemann-net +4 -104
- data/bin/riemann-nginx-status +74 -67
- data/bin/riemann-ntp +4 -33
- data/bin/riemann-portcheck +40 -31
- data/bin/riemann-proc +96 -90
- data/bin/riemann-varnish +51 -45
- data/bin/riemann-zookeeper +38 -34
- data/lib/riemann/tools/health.rb +347 -0
- data/lib/riemann/tools/net.rb +104 -0
- data/lib/riemann/tools/ntp.rb +41 -0
- data/lib/riemann/tools/version.rb +1 -1
- data/lib/riemann/tools.rb +37 -40
- data/riemann-tools.gemspec +4 -1
- data/tools/riemann-aws/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-aws/bin/riemann-aws-billing +72 -66
- data/tools/riemann-aws/bin/riemann-aws-rds-status +55 -41
- data/tools/riemann-aws/bin/riemann-aws-sqs-status +37 -31
- data/tools/riemann-aws/bin/riemann-aws-status +63 -51
- data/tools/riemann-aws/bin/riemann-elb-metrics +149 -148
- data/tools/riemann-aws/bin/riemann-s3-list +70 -65
- data/tools/riemann-aws/bin/riemann-s3-status +85 -82
- data/tools/riemann-chronos/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-chronos/bin/riemann-chronos +136 -119
- data/tools/riemann-docker/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-docker/bin/riemann-docker +163 -174
- data/tools/riemann-elasticsearch/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-elasticsearch/bin/riemann-elasticsearch +155 -147
- data/tools/riemann-marathon/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-marathon/bin/riemann-marathon +138 -122
- data/tools/riemann-mesos/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-mesos/bin/riemann-mesos +125 -110
- data/tools/riemann-munin/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-munin/bin/riemann-munin +28 -22
- data/tools/riemann-rabbitmq/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-rabbitmq/bin/riemann-rabbitmq +226 -222
- data/tools/riemann-riak/{Rakefile.rb → Rakefile} +2 -0
- data/tools/riemann-riak/bin/riemann-riak +281 -289
- data/tools/riemann-riak/riak_status/riak_status.rb +39 -39
- metadata +65 -16
data/lib/riemann/tools.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Riemann
|
2
4
|
module Tools
|
3
5
|
require 'optimist'
|
@@ -9,36 +11,36 @@ module Riemann
|
|
9
11
|
new.run
|
10
12
|
end
|
11
13
|
|
12
|
-
def opt(*
|
13
|
-
|
14
|
+
def opt(*args)
|
15
|
+
args.unshift :opt
|
14
16
|
@opts ||= []
|
15
|
-
@opts <<
|
17
|
+
@opts << args
|
16
18
|
end
|
17
19
|
|
18
20
|
def options
|
19
21
|
p = Optimist::Parser.new
|
20
22
|
@opts.each do |o|
|
21
|
-
p.send
|
23
|
+
p.send(*o)
|
22
24
|
end
|
23
|
-
Optimist
|
25
|
+
Optimist.with_standard_exception_handling(p) do
|
24
26
|
p.parse ARGV
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
opt :host,
|
29
|
-
opt :port,
|
30
|
-
opt :event_host,
|
31
|
-
opt :interval,
|
32
|
-
opt :tag,
|
33
|
-
opt :ttl,
|
34
|
-
opt :attribute,
|
35
|
-
opt :timeout,
|
36
|
-
opt :tcp,
|
37
|
-
opt :tls,
|
38
|
-
opt :tls_key,
|
39
|
-
opt :tls_cert,
|
40
|
-
opt :tls_ca_cert,
|
41
|
-
opt :tls_verify,
|
30
|
+
opt :host, 'Riemann host', default: '127.0.0.1'
|
31
|
+
opt :port, 'Riemann port', default: 5555
|
32
|
+
opt :event_host, 'Event hostname', type: String
|
33
|
+
opt :interval, 'Seconds between updates', default: 5
|
34
|
+
opt :tag, 'Tag to add to events', type: String, multi: true
|
35
|
+
opt :ttl, 'TTL for events', type: Integer
|
36
|
+
opt :attribute, 'Attribute to add to the event', type: String, multi: true
|
37
|
+
opt :timeout, 'Timeout (in seconds) when waiting for acknowledgements', default: 30
|
38
|
+
opt :tcp, 'Use TCP transport instead of UDP (improves reliability, slight overhead.', default: true
|
39
|
+
opt :tls, 'Use TLS for securing traffic', default: false
|
40
|
+
opt :tls_key, 'TLS Key to use when using TLS', type: String
|
41
|
+
opt :tls_cert, 'TLS Certificate to use when using TLS', type: String
|
42
|
+
opt :tls_ca_cert, 'Trusted CA Certificate when using TLS', type: String
|
43
|
+
opt :tls_verify, 'Verify TLS peer when using TLS', default: true
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
@@ -46,14 +48,12 @@ module Riemann
|
|
46
48
|
def options
|
47
49
|
@options ||= self.class.options
|
48
50
|
end
|
49
|
-
alias
|
51
|
+
alias opts options
|
50
52
|
|
51
53
|
def attributes
|
52
54
|
@attributes ||= Hash[options[:attribute].map do |attr|
|
53
|
-
k,v = attr.split(/=/)
|
54
|
-
if k
|
55
|
-
[k,v]
|
56
|
-
end
|
55
|
+
k, v = attr.split(/=/)
|
56
|
+
[k, v] if k && v
|
57
57
|
end]
|
58
58
|
end
|
59
59
|
|
@@ -65,9 +65,7 @@ module Riemann
|
|
65
65
|
|
66
66
|
event[:ttl] ||= (options[:ttl] || (options[:interval] * 2))
|
67
67
|
|
68
|
-
if options[:event_host]
|
69
|
-
event[:host] = options[:event_host].dup
|
70
|
-
end
|
68
|
+
event[:host] = options[:event_host].dup if options[:event_host]
|
71
69
|
|
72
70
|
event = event.merge(attributes)
|
73
71
|
|
@@ -76,14 +74,14 @@ module Riemann
|
|
76
74
|
|
77
75
|
def new_riemann_client
|
78
76
|
r = Riemann::Client.new(
|
79
|
-
:
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
77
|
+
host: options[:host],
|
78
|
+
port: options[:port],
|
79
|
+
timeout: options[:timeout],
|
80
|
+
ssl: options[:tls],
|
81
|
+
key_file: options[:tls_key],
|
82
|
+
cert_file: options[:tls_cert],
|
83
|
+
ca_file: options[:tls_ca_cert],
|
84
|
+
ssl_verify: options[:tls_verify],
|
87
85
|
)
|
88
86
|
if options[:tcp] || options[:tls]
|
89
87
|
r.tcp
|
@@ -95,15 +93,15 @@ module Riemann
|
|
95
93
|
def riemann
|
96
94
|
@riemann ||= new_riemann_client
|
97
95
|
end
|
98
|
-
alias
|
96
|
+
alias r riemann
|
99
97
|
|
100
98
|
def run
|
101
99
|
t0 = Time.now
|
102
100
|
loop do
|
103
101
|
begin
|
104
102
|
tick
|
105
|
-
rescue => e
|
106
|
-
|
103
|
+
rescue StandardError => e
|
104
|
+
warn "#{e.class} #{e}\n#{e.backtrace.join "\n"}"
|
107
105
|
end
|
108
106
|
|
109
107
|
# Sleep.
|
@@ -111,7 +109,6 @@ module Riemann
|
|
111
109
|
end
|
112
110
|
end
|
113
111
|
|
114
|
-
def tick
|
115
|
-
end
|
112
|
+
def tick; end
|
116
113
|
end
|
117
114
|
end
|
data/riemann-tools.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = 'Collection of utilities which submit events to Riemann,'
|
13
13
|
spec.homepage = 'https://github.com/aphyr/riemann-tools'
|
14
14
|
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
|
16
16
|
|
17
17
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
|
18
18
|
|
@@ -36,4 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_development_dependency 'github_changelog_generator'
|
37
37
|
spec.add_development_dependency 'rake'
|
38
38
|
spec.add_development_dependency 'rspec'
|
39
|
+
spec.add_development_dependency 'rubocop'
|
40
|
+
spec.add_development_dependency 'rubocop-rake'
|
41
|
+
spec.add_development_dependency 'rubocop-rspec'
|
39
42
|
end
|
@@ -1,84 +1,90 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
Process.setproctitle($PROGRAM_NAME)
|
3
5
|
|
4
6
|
require 'riemann/tools'
|
5
7
|
|
6
8
|
$0 = __FILE__
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
opt :fog_credential, "Fog credentials to use", :type => String
|
10
|
+
module Riemann
|
11
|
+
module Tools
|
12
|
+
class AWSBilling
|
13
|
+
include Riemann::Tools
|
14
|
+
require 'fog'
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
opt :services, "AWS services: AmazonEC2 AmazonS3 AWSDataTransfer", :type => :strings, :multi => true, :default => ["AmazonEC2", "AmazonS3", "AWSDataTransfer"]
|
16
|
+
opt :fog_credentials_file, 'Fog credentials file', type: String
|
17
|
+
opt :fog_credential, 'Fog credentials to use', type: String
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
opt :access_key, 'AWS access key', type: String
|
20
|
+
opt :secret_key, 'Secret access key', type: String
|
21
|
+
opt :services, 'AWS services: AmazonEC2 AmazonS3 AWSDataTransfer', type: :strings, multi: true,
|
22
|
+
default: %w[AmazonEC2 AmazonS3 AWSDataTransfer]
|
21
23
|
|
24
|
+
opt :time_start, 'Start time in seconds of the metrics period (2hrs ago default)', type: Integer,
|
25
|
+
default: 7200
|
26
|
+
opt :time_end, 'End time in seconds of the metrics period ', type: Integer, default: 60
|
22
27
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
def initialize
|
29
|
+
if options[:fog_credentials_file]
|
30
|
+
Fog.credentials_path = opts[:fog_credentials_file]
|
31
|
+
Fog.credential = opts[:fog_credential].to_sym
|
32
|
+
@cloudwatch = Fog::AWS::CloudWatch.new
|
33
|
+
else
|
34
|
+
creds = if opts.key?('secret_key') && opts.key?('access_key')
|
35
|
+
{
|
36
|
+
aws_secret_access_key: opts[:secret_key],
|
37
|
+
aws_access_key_id: opts[:access_key],
|
38
|
+
}
|
39
|
+
else
|
40
|
+
{ use_iam_profile: true }
|
41
|
+
end
|
42
|
+
@cloudwatch = Fog::AWS::CloudWatch.new(creds)
|
43
|
+
end
|
44
|
+
@start_time = (Time.now.utc - opts[:time_start]).iso8601
|
45
|
+
@end_time = (Time.now.utc - opts[:time_end]).iso8601
|
36
46
|
end
|
37
|
-
@cloudwatch = Fog::AWS::CloudWatch.new(creds)
|
38
|
-
end
|
39
|
-
@start_time = (Time.now.utc - opts[:time_start]).iso8601
|
40
|
-
@end_time = (Time.now.utc - opts[:time_end]).iso8601
|
41
|
-
end
|
42
|
-
|
43
|
-
def tick
|
44
|
-
opts[:services].each do |service|
|
45
|
-
data = @cloudwatch.get_metric_statistics({
|
46
|
-
'Statistics' => ["Maximum"],
|
47
|
-
'StartTime' => @start_time,
|
48
|
-
'EndTime' => @end_time,
|
49
|
-
'Period' => 3600,
|
50
|
-
'Unit' => "None",
|
51
|
-
'MetricName' => "EstimatedCharges",
|
52
|
-
'Namespace' => "AWS/Billing",
|
53
|
-
'Dimensions' => [
|
54
|
-
{
|
55
|
-
'Name' => "ServiceName",
|
56
|
-
'Value' => service
|
57
|
-
},
|
58
|
-
{
|
59
|
-
'Name' => "Currency",
|
60
|
-
'Value' => "USD"
|
61
|
-
}
|
62
|
-
]
|
63
|
-
}).body['GetMetricStatisticsResult']['Datapoints']
|
64
47
|
|
48
|
+
def tick
|
49
|
+
opts[:services].each do |service|
|
50
|
+
data = @cloudwatch.get_metric_statistics({
|
51
|
+
'Statistics' => ['Maximum'],
|
52
|
+
'StartTime' => @start_time,
|
53
|
+
'EndTime' => @end_time,
|
54
|
+
'Period' => 3600,
|
55
|
+
'Unit' => 'None',
|
56
|
+
'MetricName' => 'EstimatedCharges',
|
57
|
+
'Namespace' => 'AWS/Billing',
|
58
|
+
'Dimensions' => [
|
59
|
+
{
|
60
|
+
'Name' => 'ServiceName',
|
61
|
+
'Value' => service,
|
62
|
+
},
|
63
|
+
{
|
64
|
+
'Name' => 'Currency',
|
65
|
+
'Value' => 'USD',
|
66
|
+
},
|
67
|
+
],
|
68
|
+
}).body['GetMetricStatisticsResult']['Datapoints']
|
65
69
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
+
data.each do |metrics|
|
71
|
+
name = "AWScloudwatch.Billing.#{service}"
|
72
|
+
value = metrics['Maximum']
|
73
|
+
timestamp = metrics['Timestamp'].to_i
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
event = {
|
76
|
+
host: nil,
|
77
|
+
service: name,
|
78
|
+
time: timestamp,
|
79
|
+
description: "AWS Estimate Charges for #{service}",
|
80
|
+
tags: ['aws_billing'],
|
81
|
+
state: 'ok',
|
82
|
+
metric: value,
|
83
|
+
}
|
80
84
|
|
81
|
-
|
85
|
+
report event
|
86
|
+
end
|
87
|
+
end
|
82
88
|
end
|
83
89
|
end
|
84
90
|
end
|
@@ -1,54 +1,68 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
Process.setproctitle($PROGRAM_NAME)
|
3
5
|
|
4
6
|
require 'riemann/tools'
|
5
7
|
|
6
8
|
$0 = __FILE__ # Let's not expose our AWS keys in the process list
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
opt :secret_key, "Secret access key", :type => String
|
17
|
-
opt :region, "AWS region", :type => String, :default => 'eu-west-1'
|
18
|
-
opt :dbinstance_identifier, "DBInstanceIdentifier", :type => String
|
19
|
-
def initialize
|
20
|
-
abort "FATAL: specify a DB instance name, see --help for usage" unless opts[:dbinstance_identifier]
|
21
|
-
if opts[:access_key] and opts[:secret_key]
|
22
|
-
creds = {
|
23
|
-
:aws_access_key_id => opts[:access_key],
|
24
|
-
:aws_secret_access_key => opts[:secret_key]
|
25
|
-
}
|
26
|
-
else
|
27
|
-
creds = { :use_iam_profile => true }
|
28
|
-
end
|
29
|
-
creds['region'] = opts[:region]
|
30
|
-
@cloudwatch = Fog::AWS::CloudWatch.new(creds)
|
31
|
-
end
|
10
|
+
module Riemann
|
11
|
+
module Tools
|
12
|
+
class AWS
|
13
|
+
include Riemann::Tools
|
14
|
+
require 'fog'
|
15
|
+
require 'date'
|
16
|
+
require 'time'
|
17
|
+
require 'json'
|
32
18
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
19
|
+
opt :access_key, 'AWS access key', type: String
|
20
|
+
opt :secret_key, 'Secret access key', type: String
|
21
|
+
opt :region, 'AWS region', type: String, default: 'eu-west-1'
|
22
|
+
opt :dbinstance_identifier, 'DBInstanceIdentifier', type: String
|
23
|
+
def initialize
|
24
|
+
abort 'FATAL: specify a DB instance name, see --help for usage' unless opts[:dbinstance_identifier]
|
25
|
+
creds = if opts[:access_key] && opts[:secret_key]
|
26
|
+
{
|
27
|
+
aws_access_key_id: opts[:access_key],
|
28
|
+
aws_secret_access_key: opts[:secret_key],
|
29
|
+
}
|
30
|
+
else
|
31
|
+
{ use_iam_profile: true }
|
32
|
+
end
|
33
|
+
creds['region'] = opts[:region]
|
34
|
+
@cloudwatch = Fog::AWS::CloudWatch.new(creds)
|
48
35
|
end
|
49
36
|
|
37
|
+
def tick
|
38
|
+
time = Time.new
|
39
|
+
%w[DatabaseConnections FreeableMemory FreeStorageSpace NetworkReceiveThroughput
|
40
|
+
NetworkTransmitThroughput ReadThroughput CPUUtilization].each do |metric|
|
41
|
+
result = @cloudwatch.get_metric_statistics(
|
42
|
+
'Namespace' => 'AWS/RDS',
|
43
|
+
'MetricName' => metric.to_s,
|
44
|
+
'Statistics' => 'Average',
|
45
|
+
'Dimensions' => [{ 'Name' => 'DBInstanceIdentifier', 'Value' => opts[:dbinstance_identifier].to_s }],
|
46
|
+
'StartTime' => (time - 120).to_time.iso8601,
|
47
|
+
'EndTime' => time.to_time.iso8601, 'Period' => 60,
|
48
|
+
)
|
49
|
+
metrics_result = result.data[:body]['GetMetricStatisticsResult']
|
50
|
+
next unless metrics_result['Datapoints'].length.positive?
|
51
|
+
|
52
|
+
datapoint = metrics_result['Datapoints'][0]
|
53
|
+
ev = {
|
54
|
+
metric: datapoint['Average'],
|
55
|
+
service: "#{opts[:dbinstance_identifier]}.#{metric} (#{datapoint['Unit']})",
|
56
|
+
description: JSON.dump(metrics_result),
|
57
|
+
state: 'ok',
|
58
|
+
ttl: 300,
|
59
|
+
}
|
60
|
+
|
61
|
+
report ev
|
62
|
+
end
|
63
|
+
end
|
50
64
|
end
|
51
65
|
end
|
52
66
|
end
|
53
67
|
|
54
|
-
Riemann::Tools::AWS.run
|
68
|
+
Riemann::Tools::AWS.run
|
@@ -1,42 +1,48 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
Process.setproctitle($PROGRAM_NAME)
|
3
5
|
|
4
6
|
require 'riemann/tools'
|
5
7
|
|
6
8
|
$0 = __FILE__ # Let's not expose our AWS keys in the process list
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
module Riemann
|
11
|
+
module Tools
|
12
|
+
class AWS
|
13
|
+
include Riemann::Tools
|
14
|
+
require 'fog'
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
16
|
+
opt :access_key, 'AWS access key', type: String
|
17
|
+
opt :secret_key, 'Secret access key', type: String
|
18
|
+
opt :region, 'AWS region', type: String, default: 'us-east-1'
|
19
|
+
opt :queue, 'SQS Queue name', type: String
|
20
|
+
def initialize
|
21
|
+
creds = if opts.key?('access_key') && opts.key?('secret_key')
|
22
|
+
{
|
23
|
+
aws_access_key_id: opts[:access_key],
|
24
|
+
aws_secret_access_key: opts[:secret_key],
|
25
|
+
}
|
26
|
+
else
|
27
|
+
{ use_iam_profile: true }
|
28
|
+
end
|
29
|
+
creds['region'] = opts[:region]
|
30
|
+
@sqs = Fog::AWS::SQS.new(creds)
|
31
|
+
response = @sqs.list_queues({ 'QueueNamePrefix' => opts[:queue] })
|
32
|
+
@queue_url = response[:body]['QueueUrls'].first
|
33
|
+
end
|
30
34
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def tick
|
36
|
+
response = @sqs.get_queue_attributes(@queue_url, 'All')
|
37
|
+
%w[ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible].each do |attr|
|
38
|
+
msg = {
|
39
|
+
metric: response[:body]['Attributes'][attr],
|
40
|
+
service: "#{opts[:queue]} #{attr}",
|
41
|
+
state: 'ok',
|
42
|
+
}
|
43
|
+
report msg
|
44
|
+
end
|
45
|
+
end
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
@@ -1,68 +1,80 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
Process.setproctitle($PROGRAM_NAME)
|
3
5
|
|
4
6
|
require 'riemann/tools'
|
5
7
|
|
6
|
-
$0 = __FILE__
|
8
|
+
$0 = __FILE__ # Let's not expose our AWS keys in the process list
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
module Riemann
|
11
|
+
module Tools
|
12
|
+
class AWS
|
13
|
+
include Riemann::Tools
|
14
|
+
require 'fog'
|
15
|
+
require 'date'
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
opt :access_key, 'AWS access key', type: String
|
18
|
+
opt :secret_key, 'Secret access key', type: String
|
19
|
+
opt :region, 'AWS region', type: String, default: 'eu-west-1'
|
16
20
|
|
17
|
-
|
18
|
-
|
21
|
+
opt :retirement_critical, 'Number of days before retirement. Defaults to 2', default: 2
|
22
|
+
opt :event_warning, 'Number of days before event. Defaults to nil (i.e. when the event appears)', default: nil
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
def initialize
|
25
|
+
creds = if opts.key?('secret_key') && opts.key?('access_key')
|
26
|
+
{
|
27
|
+
aws_secret_access_key: opts[:secret_key],
|
28
|
+
aws_access_key_id: opts[:access_key],
|
29
|
+
}
|
30
|
+
else
|
31
|
+
{ use_iam_profile: true }
|
32
|
+
end
|
33
|
+
creds['region'] = opts[:region]
|
34
|
+
creds['provider'] = 'AWS'
|
35
|
+
@compute = Fog::Compute.new(creds)
|
36
|
+
end
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
def tick
|
39
|
+
# XXX: needs work:
|
40
|
+
# * instance_status and status seems unused
|
41
|
+
# * where is inject comming from
|
42
|
+
# It looks line the only needed line for the 2 next paragraph is the one that assigns hosts.
|
43
|
+
instance_status = @compute.describe_instance_status.body['instanceStatusSet']
|
44
|
+
status = instance_status.each_with_object({}) do |i, acc|
|
45
|
+
acc[i.delete('instanceId')] = i
|
46
|
+
end
|
40
47
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
48
|
+
hosts = @compute.servers.select { |s| s.state == 'running' }
|
49
|
+
inject([status, {}]) do |(astatus, acc), host|
|
50
|
+
acc[host.private_dns_name] = astatus.delete(host.id)
|
51
|
+
[astatus, acc]
|
52
|
+
end[1]
|
45
53
|
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
hosts.each do |host, host_status|
|
55
|
+
host_status['eventsSet'].each do |event|
|
56
|
+
before, _after = %w[notBefore notAfter].map { |k| Date.parse event[k].to_s if event[k] }
|
49
57
|
|
50
|
-
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
58
|
+
ev = {
|
59
|
+
host: host,
|
60
|
+
service: 'aws_instance_status',
|
61
|
+
description: "#{event['code']}\n\nstart #{event['notBefore']}\nend #{event['notAfter']}\n\n#{event['description']}",
|
62
|
+
state: 'ok',
|
63
|
+
ttl: 300,
|
64
|
+
}
|
55
65
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
66
|
+
ev2 = if (event['code'] == 'instance-retirement') &&
|
67
|
+
(Date.today >= before - opts[:retirement_critical])
|
68
|
+
{ state: 'critical' }
|
69
|
+
elsif opts[:event_warning] && (Date.today >= before - opts[:event_warning])
|
70
|
+
{ state: 'warning' }
|
71
|
+
else
|
72
|
+
{ state: 'warning' }
|
73
|
+
end
|
64
74
|
|
65
|
-
|
75
|
+
report ev.merge(ev2)
|
76
|
+
end
|
77
|
+
end
|
66
78
|
end
|
67
79
|
end
|
68
80
|
end
|