riemann-tools 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/ci.yml +13 -0
  4. data/.github/workflows/codeql-analysis.yml +72 -0
  5. data/.rubocop.yml +32 -0
  6. data/CHANGELOG.md +31 -2
  7. data/README.markdown +8 -24
  8. data/Rakefile +4 -2
  9. data/SECURITY.md +42 -0
  10. data/bin/riemann-apache-status +92 -78
  11. data/bin/riemann-bench +54 -49
  12. data/bin/riemann-cloudant +44 -40
  13. data/bin/riemann-consul +82 -76
  14. data/bin/riemann-dir-files-count +53 -47
  15. data/bin/riemann-dir-space +53 -47
  16. data/bin/riemann-diskstats +78 -75
  17. data/bin/riemann-fd +68 -48
  18. data/bin/riemann-freeswitch +108 -103
  19. data/bin/riemann-haproxy +46 -40
  20. data/bin/riemann-health +4 -343
  21. data/bin/riemann-kvminstance +18 -13
  22. data/bin/riemann-memcached +35 -29
  23. data/bin/riemann-net +4 -104
  24. data/bin/riemann-nginx-status +74 -67
  25. data/bin/riemann-ntp +4 -33
  26. data/bin/riemann-portcheck +40 -31
  27. data/bin/riemann-proc +96 -90
  28. data/bin/riemann-varnish +51 -45
  29. data/bin/riemann-zookeeper +38 -34
  30. data/lib/riemann/tools/health.rb +347 -0
  31. data/lib/riemann/tools/net.rb +104 -0
  32. data/lib/riemann/tools/ntp.rb +41 -0
  33. data/lib/riemann/tools/version.rb +1 -1
  34. data/lib/riemann/tools.rb +37 -40
  35. data/riemann-tools.gemspec +4 -1
  36. data/tools/riemann-aws/{Rakefile.rb → Rakefile} +2 -0
  37. data/tools/riemann-aws/bin/riemann-aws-billing +72 -66
  38. data/tools/riemann-aws/bin/riemann-aws-rds-status +55 -41
  39. data/tools/riemann-aws/bin/riemann-aws-sqs-status +37 -31
  40. data/tools/riemann-aws/bin/riemann-aws-status +63 -51
  41. data/tools/riemann-aws/bin/riemann-elb-metrics +149 -148
  42. data/tools/riemann-aws/bin/riemann-s3-list +70 -65
  43. data/tools/riemann-aws/bin/riemann-s3-status +85 -82
  44. data/tools/riemann-chronos/{Rakefile.rb → Rakefile} +2 -0
  45. data/tools/riemann-chronos/bin/riemann-chronos +136 -119
  46. data/tools/riemann-docker/{Rakefile.rb → Rakefile} +2 -0
  47. data/tools/riemann-docker/bin/riemann-docker +163 -174
  48. data/tools/riemann-elasticsearch/{Rakefile.rb → Rakefile} +2 -0
  49. data/tools/riemann-elasticsearch/bin/riemann-elasticsearch +155 -147
  50. data/tools/riemann-marathon/{Rakefile.rb → Rakefile} +2 -0
  51. data/tools/riemann-marathon/bin/riemann-marathon +138 -122
  52. data/tools/riemann-mesos/{Rakefile.rb → Rakefile} +2 -0
  53. data/tools/riemann-mesos/bin/riemann-mesos +125 -110
  54. data/tools/riemann-munin/{Rakefile.rb → Rakefile} +2 -0
  55. data/tools/riemann-munin/bin/riemann-munin +28 -22
  56. data/tools/riemann-rabbitmq/{Rakefile.rb → Rakefile} +2 -0
  57. data/tools/riemann-rabbitmq/bin/riemann-rabbitmq +226 -222
  58. data/tools/riemann-riak/{Rakefile.rb → Rakefile} +2 -0
  59. data/tools/riemann-riak/bin/riemann-riak +281 -289
  60. data/tools/riemann-riak/riak_status/riak_status.rb +39 -39
  61. metadata +65 -16
data/bin/riemann-cloudant CHANGED
@@ -1,59 +1,63 @@
1
1
  #!/usr/bin/env ruby
2
- Process.setproctitle($0)
2
+ # frozen_string_literal: true
3
3
 
4
- # Gathers load balancer statistics from Cloudant.com (shared cluster) and submits them to Riemann.
4
+ Process.setproctitle($PROGRAM_NAME)
5
5
 
6
- require File.expand_path('../../lib/riemann/tools', __FILE__)
6
+ # Gathers load balancer statistics from Cloudant.com (shared cluster) and submits them to Riemann.
7
7
 
8
- class Riemann::Tools::Cloudant
9
- include Riemann::Tools
10
- require 'net/http'
11
- require 'json'
8
+ require File.expand_path('../lib/riemann/tools', __dir__)
12
9
 
13
- opt :cloudant_username, "Cloudant username", :type => :string, :required => true
14
- opt :cloudant_password, "Cloudant pasword", :type => :string, :required => true
10
+ module Riemann
11
+ module Tools
12
+ class Cloudant
13
+ include Riemann::Tools
14
+ require 'net/http'
15
+ require 'json'
15
16
 
16
- def tick
17
- json = JSON.parse(get_json().body)
18
- json.each do |node|
19
- return if node['svname'] == 'BACKEND' # this is just a sum of all nodes.
17
+ opt :cloudant_username, 'Cloudant username', type: :string, required: true
18
+ opt :cloudant_password, 'Cloudant pasword', type: :string, required: true
20
19
 
21
- ns = "cloudant #{node['pxname']}"
22
- cluster_name = node['tracked'].split('.')[0] # ie: meritage.cloudant.com
20
+ def tick
21
+ json.each do |node|
22
+ break if node['svname'] == 'BACKEND' # this is just a sum of all nodes.
23
23
 
24
- # report health of each node.
25
- report(
26
- :service => ns,
27
- :state => (node['status'] == 'UP' ? 'ok' : 'critical'),
28
- :tags => ['cloudant', cluster_name]
29
- )
24
+ ns = "cloudant #{node['pxname']}"
25
+ cluster_name = node['tracked'].split('.')[0] # ie: meritage.cloudant.com
30
26
 
31
- # report property->metric of each node.
32
- node.each do |property, metric|
33
- unless ['pxname', 'svname', 'status', 'tracked'].include?(property)
27
+ # report health of each node.
34
28
  report(
35
- :host => node['tracked'],
36
- :service => "#{ns} #{property}",
37
- :metric => metric.to_f,
38
- :state => (node['status'] == 'UP' ? 'ok' : 'critical'),
39
- :tags => ['cloudant', cluster_name]
29
+ service: ns,
30
+ state: (node['status'] == 'UP' ? 'ok' : 'critical'),
31
+ tags: ['cloudant', cluster_name],
40
32
  )
33
+
34
+ # report property->metric of each node.
35
+ node.each do |property, metric|
36
+ next if %w[pxname svname status tracked].include?(property)
37
+
38
+ report(
39
+ host: node['tracked'],
40
+ service: "#{ns} #{property}",
41
+ metric: metric.to_f,
42
+ state: (node['status'] == 'UP' ? 'ok' : 'critical'),
43
+ tags: ['cloudant', cluster_name],
44
+ )
45
+ end
41
46
  end
42
47
  end
43
48
 
49
+ def json
50
+ http = Net::HTTP.new('cloudant.com', 443)
51
+ http.use_ssl = true
52
+ http.start do |h|
53
+ get = Net::HTTP::Get.new('/api/load_balancer')
54
+ get.basic_auth opts[:cloudant_username], opts[:cloudant_password]
55
+ h.request get
56
+ end
57
+ JSON.parse(http.boby)
58
+ end
44
59
  end
45
60
  end
46
-
47
- def get_json
48
- http = Net::HTTP.new('cloudant.com', 443)
49
- http.use_ssl = true
50
- http.start do |h|
51
- get = Net::HTTP::Get.new('/api/load_balancer')
52
- get.basic_auth opts[:cloudant_username], opts[:cloudant_password]
53
- h.request get
54
- end
55
- end
56
-
57
61
  end
58
62
 
59
63
  Riemann::Tools::Cloudant.run
data/bin/riemann-consul CHANGED
@@ -1,106 +1,112 @@
1
1
  #!/usr/bin/env ruby
2
- Process.setproctitle($0)
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
3
5
 
4
6
  # Reports service and node status to riemann
5
7
 
6
- require File.expand_path('../../lib/riemann/tools', __FILE__)
8
+ require File.expand_path('../lib/riemann/tools', __dir__)
7
9
  require 'socket'
8
10
  require 'net/http'
9
11
  require 'uri'
10
12
  require 'json'
11
13
 
12
- class Riemann::Tools::ConsulHealth
13
- include Riemann::Tools
14
-
15
- opt :consul_host, "Consul API Host (default to localhost)", :default => "localhost"
16
- opt :consul_port, "Consul API Host (default to 8500)", :default => "8500"
17
- opt :prefix, "prefix to use for all service names when reporting", :default => "consul "
18
- opt :minimum_services_per_node, "minimum services per node (default: 0)", :default => 0
19
-
20
- def initialize
21
-
22
- @hostname = opts[:consul_host]
23
- @prefix = opts[:prefix]
24
- @minimum_services_per_node = opts[:minimum_services_per_node]
25
- @underlying_ip = IPSocket.getaddress(@hostname)
26
- @consul_leader_url = URI.parse("http://" + opts[:consul_host] + ":" + opts[:consul_port] + "/v1/status/leader")
27
- @consul_services_url = URI.parse("http://" + opts[:consul_host] + ":" + opts[:consul_port] + "/v1/catalog/services")
28
- @consul_nodes_url = URI.parse("http://" + opts[:consul_host] + ":" + opts[:consul_port] + "/v1/catalog/nodes")
29
- @consul_health_url_prefix = "http://" + opts[:consul_host] + ":" + opts[:consul_port] + "/v1/health/service/"
30
-
31
- @last_services_read = Hash.new
32
-
33
- end
14
+ module Riemann
15
+ module Tools
16
+ class ConsulHealth
17
+ include Riemann::Tools
18
+
19
+ opt :consul_host, 'Consul API Host (default to localhost)', default: 'localhost'
20
+ opt :consul_port, 'Consul API Host (default to 8500)', default: '8500'
21
+ opt :prefix, 'prefix to use for all service names when reporting', default: 'consul '
22
+ opt :minimum_services_per_node, 'minimum services per node (default: 0)', default: 0
23
+
24
+ def initialize
25
+ @hostname = opts[:consul_host]
26
+ @prefix = opts[:prefix]
27
+ @minimum_services_per_node = opts[:minimum_services_per_node]
28
+ @underlying_ip = IPSocket.getaddress(@hostname)
29
+ @consul_leader_url = URI.parse("http://#{opts[:consul_host]}:#{opts[:consul_port]}/v1/status/leader")
30
+ @consul_services_url = URI.parse("http://#{opts[:consul_host]}:#{opts[:consul_port]}/v1/catalog/services")
31
+ @consul_nodes_url = URI.parse("http://#{opts[:consul_host]}:#{opts[:consul_port]}/v1/catalog/nodes")
32
+ @consul_health_url_prefix = "http://#{opts[:consul_host]}:#{opts[:consul_port]}/v1/health/service/"
33
+
34
+ @last_services_read = {}
35
+ end
34
36
 
35
- def alert(hostname, service, state, metric, description)
37
+ def alert(hostname, service, state, metric, description)
38
+ opts = {
39
+ host: hostname,
40
+ service: service.to_s,
41
+ state: state.to_s,
42
+ metric: metric,
43
+ description: description,
44
+ }
36
45
 
37
- opts = { :host => hostname,
38
- :service => service.to_s,
39
- :state => state.to_s,
40
- :metric => metric,
41
- :description => description }
46
+ report(opts)
47
+ end
42
48
 
43
- report(opts)
44
- end
49
+ def get(url)
50
+ Net::HTTP.get_response(url).body
51
+ end
45
52
 
46
- def get(url)
47
- Net::HTTP.get_response(url).body
48
- end
53
+ def tick
54
+ leader = JSON.parse(get(@consul_leader_url))
55
+ leader_hostname = URI.parse("http://#{leader}").hostname
49
56
 
50
- def tick
57
+ return unless leader_hostname == @underlying_ip
51
58
 
52
- leader = JSON.parse(get(@consul_leader_url))
53
- leader_hostname = URI.parse("http://" + leader).hostname
59
+ nodes = JSON.parse(get(@consul_nodes_url))
60
+ services = JSON.parse(get(@consul_services_url))
61
+ services_by_nodes = {}
54
62
 
55
- if (leader_hostname == @underlying_ip)
56
- nodes = JSON.parse(get(@consul_nodes_url))
57
- services = JSON.parse(get(@consul_services_url))
58
- services_by_nodes = Hash.new
63
+ nodes.each do |node|
64
+ node_name = node['Node']
65
+ services_by_nodes[node_name] = 0
66
+ end
59
67
 
60
- for node in nodes
61
- node_name = node["Node"]
62
- services_by_nodes[node_name] = 0
63
- end
68
+ # For every service
69
+ services.each do |service|
70
+ service_name = service[0]
71
+ health_url = URI.parse(@consul_health_url_prefix + service_name)
72
+ health_nodes = JSON.parse(get(health_url))
64
73
 
74
+ total_count = 0
75
+ ok_count = 0
65
76
 
66
- # For every service
67
- for service in services
68
- service_name = service[0]
69
- health_url = URI.parse(@consul_health_url_prefix + service_name)
70
- health_nodes = JSON.parse(get(health_url))
77
+ health_nodes.each do |node|
78
+ hostname = node['Node']['Node']
79
+ ok = node['Checks'].all? { |check| check['Status'] == 'passing' }
80
+ alert(hostname, "#{@prefix}#{service_name}", ok ? :ok : :critical, ok ? 1 : 0, JSON.generate(node))
81
+ total_count += 1
82
+ ok_count += ok ? 1 : 0
71
83
 
72
- totalCount = 0
73
- okCount = 0
84
+ last_services_by_nodes = services_by_nodes[hostname].to_i
85
+ services_by_nodes[hostname] = last_services_by_nodes + 1
86
+ end
74
87
 
75
- for node in health_nodes
76
- hostname = node["Node"]["Node"]
77
- ok = node["Checks"].all? {|check| check["Status"] == "passing"}
78
- alert(hostname, "#{@prefix}#{service_name}", ok ? :ok : :critical, ok ? 1 : 0, JSON.generate(node))
79
- totalCount += 1
80
- okCount += ok ? 1 : 0
88
+ unless @last_services_read[service_name].nil?
89
+ last_ok = @last_services_read[service_name]
90
+ if last_ok != ok_count
91
+ alert(
92
+ 'total', "#{@prefix}#{service_name}-count", ok_count >= last_ok ? :ok : :critical, ok_count,
93
+ "Number of passing #{service_name} is: #{ok_count}/#{total_count}, Last time it was: #{last_ok}",
94
+ )
95
+ end
96
+ end
81
97
 
82
- last_services_by_nodes = services_by_nodes[hostname].to_i
83
- services_by_nodes[hostname] = last_services_by_nodes + 1
98
+ @last_services_read[service_name] = ok_count
84
99
  end
85
100
 
86
- if (@last_services_read[service_name] != nil)
87
- lastOk = @last_services_read[service_name]
88
- if (lastOk != okCount)
89
- alert("total", "#{@prefix}#{service_name}-count", okCount >= lastOk ? :ok : :critical, okCount, "Number of passing #{service_name} is: #{okCount}/#{totalCount}, Last time it was: #{lastOk}")
90
- end
101
+ # For every node
102
+ services_by_nodes.each do |node, count|
103
+ alert(
104
+ node, "#{@prefix}total-services", count >= @minimum_services_per_node ? :ok : :critical, count,
105
+ "#{count} services in the specified node",
106
+ )
91
107
  end
92
-
93
- @last_services_read[service_name] = okCount
94
-
95
- end
96
-
97
- # For every node
98
- for node,count in services_by_nodes
99
- alert(node, "#{@prefix}total-services", (count >= @minimum_services_per_node) ? :ok : :critical, count, "#{count} services in the specified node")
100
108
  end
101
-
102
109
  end
103
-
104
110
  end
105
111
  end
106
112
 
@@ -1,54 +1,60 @@
1
1
  #!/usr/bin/env ruby
2
- Process.setproctitle($0)
2
+ # frozen_string_literal: true
3
3
 
4
- # Gets the number of files present on a directory and submits it to riemann
5
-
6
- require File.expand_path('../../lib/riemann/tools', __FILE__)
7
-
8
- class Riemann::Tools::DirFilesCount
9
- include Riemann::Tools
4
+ Process.setproctitle($PROGRAM_NAME)
10
5
 
11
- opt :directory, "", :default => '/var/log'
12
- opt :service_prefix, "The first part of the service name, before the directory path", :default => "dir-files-count"
13
- opt :warning, "Dir files number warning threshold", :type => Integer
14
- opt :critical, "Dir files number critical threshold", :type => Integer
15
- opt :alert_on_missing, "Send a critical metric if the directory is missing?", :default => true
16
-
17
- def initialize
18
- @dir = opts.fetch(:directory)
19
- @service_prefix = opts.fetch(:service_prefix)
20
- @warning = opts.fetch(:warning, nil)
21
- @critical = opts.fetch(:critical, nil)
22
- @alert_on_missing = opts.fetch(:alert_on_missing)
23
- end
24
-
25
- def tick
26
- if Dir.exists?(@dir)
27
- metric = Dir.entries(@dir).size - 2
28
- report(
29
- :service => "#{@service_prefix} #{@dir}",
30
- :metric => metric,
31
- :state => state(metric),
32
- :tags => ['dir_files_count']
33
- )
34
- elsif @alert_on_missing
35
- report(
36
- :service => "#{@service_prefix} #{@dir} missing",
37
- :description => "#{@service_prefix} #{@dir} does not exist",
38
- :metric => metric,
39
- :state => 'critical',
40
- :tags => ['dir_files_count']
41
- )
42
- end
43
- end
6
+ # Gets the number of files present on a directory and submits it to riemann
44
7
 
45
- def state(metric)
46
- if @critical && metric > @critical
47
- 'critical'
48
- elsif @warning && metric > @warning
49
- 'warning'
50
- else
51
- 'ok'
8
+ require File.expand_path('../lib/riemann/tools', __dir__)
9
+
10
+ module Riemann
11
+ module Tools
12
+ class DirFilesCount
13
+ include Riemann::Tools
14
+
15
+ opt :directory, '', default: '/var/log'
16
+ opt :service_prefix, 'The first part of the service name, before the directory path', default: 'dir-files-count'
17
+ opt :warning, 'Dir files number warning threshold', type: Integer
18
+ opt :critical, 'Dir files number critical threshold', type: Integer
19
+ opt :alert_on_missing, 'Send a critical metric if the directory is missing?', default: true
20
+
21
+ def initialize
22
+ @dir = opts.fetch(:directory)
23
+ @service_prefix = opts.fetch(:service_prefix)
24
+ @warning = opts.fetch(:warning, nil)
25
+ @critical = opts.fetch(:critical, nil)
26
+ @alert_on_missing = opts.fetch(:alert_on_missing)
27
+ end
28
+
29
+ def tick
30
+ if Dir.exist?(@dir)
31
+ metric = Dir.entries(@dir).size - 2
32
+ report(
33
+ service: "#{@service_prefix} #{@dir}",
34
+ metric: metric,
35
+ state: state(metric),
36
+ tags: ['dir_files_count'],
37
+ )
38
+ elsif @alert_on_missing
39
+ report(
40
+ service: "#{@service_prefix} #{@dir} missing",
41
+ description: "#{@service_prefix} #{@dir} does not exist",
42
+ metric: metric,
43
+ state: 'critical',
44
+ tags: ['dir_files_count'],
45
+ )
46
+ end
47
+ end
48
+
49
+ def state(metric)
50
+ if @critical && metric > @critical
51
+ 'critical'
52
+ elsif @warning && metric > @warning
53
+ 'warning'
54
+ else
55
+ 'ok'
56
+ end
57
+ end
52
58
  end
53
59
  end
54
60
  end
@@ -1,54 +1,60 @@
1
1
  #!/usr/bin/env ruby
2
- Process.setproctitle($0)
2
+ # frozen_string_literal: true
3
3
 
4
- # Gathers the space used by a directory and submits it to riemann
5
-
6
- require File.expand_path('../../lib/riemann/tools', __FILE__)
7
-
8
- class Riemann::Tools::DirSpace
9
- include Riemann::Tools
4
+ Process.setproctitle($PROGRAM_NAME)
10
5
 
11
- opt :directory, "", :default => '/var/log'
12
- opt :service_prefix, "The first part of the service name, before the directory path", :default => "dir-space"
13
- opt :warning, "Dir space warning threshold (in bytes)", :type => Integer
14
- opt :critical, "Dir space critical threshold (in bytes)", :type => Integer
15
- opt :alert_on_missing, "Send a critical metric if the directory is missing?", :default => true
16
-
17
- def initialize
18
- @dir = opts.fetch(:directory)
19
- @service_prefix = opts.fetch(:service_prefix)
20
- @warning = opts.fetch(:warning, nil)
21
- @critical = opts.fetch(:critical, nil)
22
- @alert_on_missing = opts.fetch(:alert_on_missing)
23
- end
24
-
25
- def tick
26
- if Dir.exists?(@dir)
27
- metric = `du '#{@dir}'`.lines.to_a.last.split("\t")[0].to_i
28
- report(
29
- :service => "#{@service_prefix} #{@dir}",
30
- :metric => metric,
31
- :state => state(metric),
32
- :tags => ['dir_space']
33
- )
34
- elsif @alert_on_missing
35
- report(
36
- :service => "#{@service_prefix} #{@dir} missing",
37
- :description => "#{@service_prefix} #{@dir} does not exist",
38
- :metric => metric,
39
- :state => 'critical',
40
- :tags => ['dir_space']
41
- )
42
- end
43
- end
6
+ # Gathers the space used by a directory and submits it to riemann
44
7
 
45
- def state(metric)
46
- if @critical && metric > @critical
47
- 'critical'
48
- elsif @warning && metric > @warning
49
- 'warning'
50
- else
51
- 'ok'
8
+ require File.expand_path('../lib/riemann/tools', __dir__)
9
+
10
+ module Riemann
11
+ module Tools
12
+ class DirSpace
13
+ include Riemann::Tools
14
+
15
+ opt :directory, '', default: '/var/log'
16
+ opt :service_prefix, 'The first part of the service name, before the directory path', default: 'dir-space'
17
+ opt :warning, 'Dir space warning threshold (in bytes)', type: Integer
18
+ opt :critical, 'Dir space critical threshold (in bytes)', type: Integer
19
+ opt :alert_on_missing, 'Send a critical metric if the directory is missing?', default: true
20
+
21
+ def initialize
22
+ @dir = opts.fetch(:directory)
23
+ @service_prefix = opts.fetch(:service_prefix)
24
+ @warning = opts.fetch(:warning, nil)
25
+ @critical = opts.fetch(:critical, nil)
26
+ @alert_on_missing = opts.fetch(:alert_on_missing)
27
+ end
28
+
29
+ def tick
30
+ if Dir.exist?(@dir)
31
+ metric = `du '#{@dir}'`.lines.to_a.last.split("\t")[0].to_i
32
+ report(
33
+ service: "#{@service_prefix} #{@dir}",
34
+ metric: metric,
35
+ state: state(metric),
36
+ tags: ['dir_space'],
37
+ )
38
+ elsif @alert_on_missing
39
+ report(
40
+ service: "#{@service_prefix} #{@dir} missing",
41
+ description: "#{@service_prefix} #{@dir} does not exist",
42
+ metric: metric,
43
+ state: 'critical',
44
+ tags: ['dir_space'],
45
+ )
46
+ end
47
+ end
48
+
49
+ def state(metric)
50
+ if @critical && metric > @critical
51
+ 'critical'
52
+ elsif @warning && metric > @warning
53
+ 'warning'
54
+ else
55
+ 'ok'
56
+ end
57
+ end
52
58
  end
53
59
  end
54
60
  end