riemann-tools 0.2.13 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +5 -5
  2. data/.docker/Dockerfile +7 -0
  3. data/.docker/publish.sh +35 -0
  4. data/.github/dependabot.yml +11 -0
  5. data/.github/workflows/ci.yml +42 -0
  6. data/.github/workflows/codeql-analysis.yml +72 -0
  7. data/.gitignore +6 -0
  8. data/.rspec +2 -0
  9. data/.rubocop.yml +32 -0
  10. data/.travis.yml +31 -0
  11. data/CHANGELOG.md +422 -0
  12. data/Gemfile +6 -0
  13. data/ISSUE_TEMPLATE.md +15 -0
  14. data/README.markdown +14 -15
  15. data/Rakefile +23 -0
  16. data/SECURITY.md +42 -0
  17. data/bin/riemann-apache-status +92 -77
  18. data/bin/riemann-bench +54 -48
  19. data/bin/riemann-cloudant +44 -39
  20. data/bin/riemann-consul +82 -75
  21. data/bin/riemann-dir-files-count +53 -46
  22. data/bin/riemann-dir-space +53 -46
  23. data/bin/riemann-diskstats +78 -74
  24. data/bin/riemann-fd +68 -47
  25. data/bin/riemann-freeswitch +108 -102
  26. data/bin/riemann-haproxy +46 -39
  27. data/bin/riemann-health +4 -335
  28. data/bin/riemann-kvminstance +18 -12
  29. data/bin/riemann-memcached +35 -28
  30. data/bin/riemann-net +4 -103
  31. data/bin/riemann-nginx-status +74 -66
  32. data/bin/riemann-ntp +4 -32
  33. data/bin/riemann-portcheck +40 -30
  34. data/bin/riemann-proc +96 -89
  35. data/bin/riemann-varnish +51 -44
  36. data/bin/riemann-zookeeper +38 -33
  37. data/lib/riemann/tools/health.rb +347 -0
  38. data/lib/riemann/tools/net.rb +104 -0
  39. data/lib/riemann/tools/ntp.rb +41 -0
  40. data/lib/riemann/tools/utils.rb +17 -0
  41. data/lib/riemann/tools/version.rb +7 -0
  42. data/lib/riemann/tools.rb +40 -33
  43. data/riemann-tools.gemspec +42 -0
  44. data/tools/riemann-aws/LICENSE +21 -0
  45. data/tools/riemann-aws/README.md +54 -0
  46. data/tools/riemann-aws/Rakefile +37 -0
  47. data/tools/riemann-aws/bin/riemann-aws-billing +93 -0
  48. data/tools/riemann-aws/bin/riemann-aws-rds-status +68 -0
  49. data/tools/riemann-aws/bin/riemann-aws-sqs-status +50 -0
  50. data/tools/riemann-aws/bin/riemann-aws-status +83 -0
  51. data/tools/riemann-aws/bin/riemann-elb-metrics +168 -0
  52. data/tools/riemann-aws/bin/riemann-s3-list +87 -0
  53. data/tools/riemann-aws/bin/riemann-s3-status +102 -0
  54. data/tools/riemann-chronos/LICENSE +21 -0
  55. data/tools/riemann-chronos/README.md +10 -0
  56. data/tools/riemann-chronos/Rakefile +37 -0
  57. data/tools/riemann-chronos/bin/riemann-chronos +161 -0
  58. data/tools/riemann-docker/LICENSE +21 -0
  59. data/tools/riemann-docker/README.md +10 -0
  60. data/tools/riemann-docker/Rakefile +36 -0
  61. data/tools/riemann-docker/bin/riemann-docker +206 -0
  62. data/tools/riemann-elasticsearch/LICENSE +21 -0
  63. data/tools/riemann-elasticsearch/README.md +10 -0
  64. data/tools/riemann-elasticsearch/Rakefile +37 -0
  65. data/tools/riemann-elasticsearch/bin/riemann-elasticsearch +174 -0
  66. data/tools/riemann-marathon/LICENSE +21 -0
  67. data/tools/riemann-marathon/README.md +10 -0
  68. data/tools/riemann-marathon/Rakefile +37 -0
  69. data/tools/riemann-marathon/bin/riemann-marathon +163 -0
  70. data/tools/riemann-mesos/LICENSE +21 -0
  71. data/tools/riemann-mesos/README.md +10 -0
  72. data/tools/riemann-mesos/Rakefile +37 -0
  73. data/tools/riemann-mesos/bin/riemann-mesos +146 -0
  74. data/tools/riemann-munin/LICENSE +21 -0
  75. data/tools/riemann-munin/README.md +10 -0
  76. data/tools/riemann-munin/Rakefile +36 -0
  77. data/tools/riemann-munin/bin/riemann-munin +43 -0
  78. data/tools/riemann-rabbitmq/LICENSE +21 -0
  79. data/tools/riemann-rabbitmq/README.md +10 -0
  80. data/tools/riemann-rabbitmq/Rakefile +37 -0
  81. data/tools/riemann-rabbitmq/bin/riemann-rabbitmq +273 -0
  82. data/tools/riemann-riak/LICENSE +21 -0
  83. data/tools/riemann-riak/README.md +10 -0
  84. data/tools/riemann-riak/Rakefile +36 -0
  85. data/tools/riemann-riak/bin/riemann-riak +323 -0
  86. data/tools/riemann-riak/bin/riemann-riak-keys +13 -0
  87. data/tools/riemann-riak/bin/riemann-riak-ring +9 -0
  88. data/tools/riemann-riak/riak_status/key_count.erl +13 -0
  89. data/tools/riemann-riak/riak_status/riak_status.rb +152 -0
  90. data/tools/riemann-riak/riak_status/ringready.erl +9 -0
  91. metadata +195 -34
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ $0 = __FILE__
9
+
10
+ module Riemann
11
+ module Tools
12
+ class S3Metrics
13
+ include Riemann::Tools
14
+ require 'fog'
15
+ require 'time'
16
+
17
+ opt :fog_credentials_file, 'Fog credentials file', type: String
18
+ opt :fog_credential, 'Fog credentials to use', type: String
19
+ opt :aws_access, 'AWS Access Key', type: String
20
+ opt :aws_secret, 'AWS Secret Key', type: String
21
+ opt :aws_region, 'AWS Region', type: String, default: 'eu-west-1'
22
+ opt :buckets, 'Buckets to pull metrics from, multi=true, can have a prefix like mybucket/prefix', type: String,
23
+ multi: true, required: true
24
+ opt :max_objects, 'Max number of objects to list before stopping to save bandwidth', default: -1
25
+
26
+ def tick
27
+ if options[:fog_credentials_file]
28
+ Fog.credentials_path = options[:fog_credentials_file]
29
+ Fog.credential = options[:fog_credential].to_sym
30
+ connection = Fog::Storage.new
31
+ else
32
+ connection = if options[:aws_access] && options[:aws_secret]
33
+ Fog::Storage.new({
34
+ provider: 'AWS',
35
+ aws_access_key_id: options[:aws_access],
36
+ aws_secret_access_key: options[:aws_secret],
37
+ region: options[:aws_region],
38
+ })
39
+ else
40
+ Fog::Storage.new({
41
+ provider: 'AWS',
42
+ use_iam_profile: true,
43
+ region: options[:aws_region],
44
+ })
45
+ end
46
+ end
47
+
48
+ options[:buckets].each do |url|
49
+ split = url.split('/')
50
+ bucket = split[0]
51
+ prefix = ''
52
+ prefix = url[(split[0].length + 1)..] if split[1]
53
+ count = 0
54
+ connection.directories.get(bucket, prefix: prefix).files.map do |_file|
55
+ count += 1
56
+ break if options[:max_objects].positive? && count > options[:max_objects]
57
+ end
58
+ event = if options[:max_objects].positive? && count > options[:max_objects]
59
+ event(
60
+ url, 'objectCount', count, "count was bigger than threshold #{options[:max_objects]}",
61
+ 'warning',
62
+ )
63
+ else
64
+ event(url, 'objectCount', count, "All objects counted, threshold=#{options[:max_objects]}", 'ok')
65
+ end
66
+ report(event)
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def event(bucket, label, metric, description, severity)
73
+ {
74
+ host: "bucket_#{bucket}",
75
+ service: "s3.#{label}",
76
+ ttl: 300,
77
+ description: "#{bucket} #{description}",
78
+ tags: ['s3_metrics'],
79
+ metric: metric,
80
+ state: severity,
81
+ }
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ Riemann::Tools::S3Metrics.run
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ $0 = __FILE__
9
+
10
+ module Riemann
11
+ module Tools
12
+ class S3Metrics
13
+ include Riemann::Tools
14
+ require 'fog'
15
+ require 'time'
16
+
17
+ opt :fog_credentials_file, 'Fog credentials file', type: String
18
+ opt :fog_credential, 'Fog credentials to use', type: String
19
+ opt :aws_access, 'AWS Access Key', type: String
20
+ opt :aws_secret, 'AWS Secret Key', type: String
21
+ opt :aws_region, 'AWS Region', type: String, default: 'eu-west-1'
22
+ opt :buckets, 'Buckets to pull metrics from, multi=true', type: String, multi: true, required: true
23
+ opt :statistic, 'Statistic to retrieve, multi=true, e.g. --statistic=Average --statistic=Maximum', type: String,
24
+ multi: true, required: true
25
+
26
+ def base_metrics
27
+ # get last 60 seconds
28
+ start_time = (Time.now.utc - 3600 * 24 * 1).iso8601
29
+ end_time = Time.now.utc.iso8601
30
+
31
+ # The base query that all metrics would get
32
+ {
33
+ 'Namespace' => 'AWS/S3',
34
+ 'StartTime' => start_time,
35
+ 'EndTime' => end_time,
36
+ 'Period' => 3600,
37
+ 'MetricName' => 'NumberOfObjects',
38
+ }
39
+ end
40
+
41
+ def tick
42
+ if options[:fog_credentials_file]
43
+ Fog.credentials_path = options[:fog_credentials_file]
44
+ Fog.credential = options[:fog_credential].to_sym
45
+ connection = Fog::AWS::CloudWatch.new
46
+ else
47
+ connection = if options[:aws_access] && options[:aws_secret]
48
+ Fog::AWS::CloudWatch.new({
49
+ aws_access_key_id: options[:aws_access],
50
+ aws_secret_access_key: options[:aws_secret],
51
+ region: options[:aws_region],
52
+ })
53
+ else
54
+ Fog::AWS::CloudWatch.new({
55
+ use_iam_profile: true,
56
+ region: options[:aws_region],
57
+ })
58
+ end
59
+ end
60
+
61
+ options[:statistic].each do |statistic|
62
+ options[:buckets].each do |bucket|
63
+ metric_base_options = base_metrics
64
+ metric_base_options['Statistics'] = statistic
65
+ metric_base_options['Dimensions'] = [
66
+ { 'Name' => 'BucketName', 'Value' => bucket },
67
+ { 'Name' => 'StorageType', 'Value' => 'AllStorageTypes' },
68
+ ]
69
+
70
+ result = connection.get_metric_statistics(metric_base_options)
71
+ next if result.body['GetMetricStatisticsResult']['Datapoints'].empty?
72
+
73
+ result.body['GetMetricStatisticsResult']['Datapoints'][0].keys.sort.each do |stat_type|
74
+ next if stat_type == 'Unit'
75
+ next if stat_type == 'Timestamp'
76
+
77
+ unit = result.body['GetMetricStatisticsResult']['Datapoints'][0]['Unit']
78
+ metric = result.body['GetMetricStatisticsResult']['Datapoints'][0][stat_type]
79
+ event = event(bucket, result.body['GetMetricStatisticsResult']['Label'], stat_type, unit, metric)
80
+ report(event)
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def event(bucket, label, metric_type, stat_type, metric, unit = nil)
89
+ {
90
+ host: "bucket_#{bucket}",
91
+ service: "s3.#{label}.#{metric_type}.#{stat_type}",
92
+ ttl: 300,
93
+ description: "#{bucket} #{metric_type} #{stat_type} (#{unit})",
94
+ tags: ['s3_metrics'],
95
+ metric: metric,
96
+ }
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ Riemann::Tools::S3Metrics.run
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Kyle Kingsbury
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,10 @@
1
+ # Riemann Chronos
2
+
3
+ Gathers Chronos metrics and sends them to Riemann.
4
+
5
+ # Getting started
6
+
7
+ ```
8
+ gem install riemann-chronos
9
+ riemann-chronos --help
10
+ ```
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'rubygems/package_task'
5
+ require 'rdoc/task'
6
+ require 'find'
7
+
8
+ # Don't include resource forks in tarballs on Mac OS X.
9
+ ENV['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
10
+ ENV['COPYFILE_DISABLE'] = 'true'
11
+
12
+ # Gemspec
13
+ gemspec = Gem::Specification.new do |s|
14
+ s.rubyforge_project = 'riemann-chronos'
15
+
16
+ s.name = 'riemann-chronos'
17
+ s.version = '0.1.1'
18
+ s.author = 'Peter Ericson'
19
+ s.email = 'peter.ericson@cba.com.au'
20
+ s.homepage = 'https://github.com/riemann/riemann-tools'
21
+ s.platform = Gem::Platform::RUBY
22
+ s.summary = 'Submits Chronos stats to riemann.'
23
+ s.license = 'MIT'
24
+
25
+ s.add_dependency 'riemann-tools', '>= 0.2.13'
26
+ s.add_dependency 'faraday', '>= 0.8.5'
27
+ s.add_dependency 'json'
28
+
29
+ s.files = FileList['bin/*', 'LICENSE', 'README.md'].to_a
30
+ s.executables |= Dir.entries('bin/')
31
+ s.has_rdoc = false
32
+
33
+ s.required_ruby_version = '>= 1.8.7'
34
+ end
35
+
36
+ Gem::PackageTask.new gemspec do |p|
37
+ end
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools'
7
+
8
+ module Riemann
9
+ module Tools
10
+ class Chronos
11
+ include Riemann::Tools
12
+
13
+ require 'faraday'
14
+ require 'json'
15
+ require 'uri'
16
+
17
+ opt :read_timeout, 'Faraday read timeout', type: :int, default: 2
18
+ opt :open_timeout, 'Faraday open timeout', type: :int, default: 1
19
+ opt :path_prefix,
20
+ 'Chronos path prefix for proxied installations e.g. "chronos" for target http://localhost/chronos/metrics', default: '/'
21
+ opt :chronos_host, 'Chronos host', default: 'localhost'
22
+ opt :chronos_port, 'Chronos port', type: :int, default: 4400
23
+
24
+ def initialize
25
+ options[:interval] = 60
26
+ options[:ttl] = 120
27
+ end
28
+
29
+ # Handles HTTP connections and GET requests safely
30
+ def safe_get(uri)
31
+ # Handle connection timeouts
32
+ response = nil
33
+ begin
34
+ connection = Faraday.new(uri)
35
+ response = connection.get do |req|
36
+ req.options[:timeout] = options[:read_timeout]
37
+ req.options[:open_timeout] = options[:open_timeout]
38
+ end
39
+ rescue StandardError => e
40
+ report(
41
+ host: uri.host,
42
+ service: 'chronos health',
43
+ state: 'critical',
44
+ description: "HTTP connection error: #{e.class} - #{e.message}",
45
+ )
46
+ end
47
+ response
48
+ end
49
+
50
+ def health_url
51
+ path_prefix = options[:path_prefix]
52
+ path_prefix[0] = '' if path_prefix[0] == '/'
53
+ path_prefix[path_prefix.length - 1] = '' if path_prefix[path_prefix.length - 1] == '/'
54
+ "http://#{options[:chronos_host]}:#{options[:chronos_port]}#{path_prefix.length.positive? ? '/' : ''}#{path_prefix}/metrics"
55
+ end
56
+
57
+ def jobs_url
58
+ path_prefix = options[:path_prefix]
59
+ path_prefix[0] = '' if path_prefix[0] == '/'
60
+ path_prefix[path_prefix.length - 1] = '' if path_prefix[path_prefix.length - 1] == '/'
61
+ "http://#{options[:chronos_host]}:#{options[:chronos_port]}#{path_prefix.length.positive? ? '/' : ''}#{path_prefix}/scheduler/jobs"
62
+ end
63
+
64
+ def tick
65
+ tick_health
66
+ tick_jobs
67
+ end
68
+
69
+ def tick_health
70
+ uri = URI(health_url)
71
+ response = safe_get(uri)
72
+
73
+ return if response.nil?
74
+
75
+ if response.status != 200
76
+ report(
77
+ host: uri.host,
78
+ service: 'chronos health',
79
+ state: 'critical',
80
+ description: "HTTP connection error: #{response.status} - #{response.body}",
81
+ )
82
+ else
83
+ # Assuming that a 200 will give json
84
+ json = JSON.parse(response.body)
85
+
86
+ report(
87
+ host: uri.host,
88
+ service: 'chronos health',
89
+ state: 'ok',
90
+ )
91
+
92
+ json.each_pair do |t, d|
93
+ next unless d.respond_to? :each_pair
94
+
95
+ d.each_pair do |service, counters|
96
+ report(
97
+ host: uri.host,
98
+ service: "chronos_metric #{t} #{service}",
99
+ metric: 1,
100
+ tags: ['metric_name'],
101
+ ttl: 600,
102
+ )
103
+ next unless counters.respond_to? :each_pair
104
+
105
+ counters.each_pair do |k, v|
106
+ next unless v.is_a? Numeric
107
+
108
+ report(
109
+ host: uri.host,
110
+ service: "chronos #{service} #{k}",
111
+ metric: v,
112
+ tags: ['metric', t.to_s],
113
+ ttl: 600,
114
+ )
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ def tick_jobs
122
+ uri = URI(jobs_url)
123
+ response = safe_get(uri)
124
+
125
+ return if response.nil?
126
+
127
+ if response.status != 200
128
+ report(
129
+ host: uri.host,
130
+ service: 'chronos health',
131
+ state: 'critical',
132
+ description: "HTTP connection error: #{response.status} - #{response.body}",
133
+ )
134
+ else
135
+ # Assuming that a 200 will give json
136
+ json = JSON.parse(response.body)
137
+
138
+ report(
139
+ host: uri.host,
140
+ service: 'chronos health',
141
+ state: 'ok',
142
+ )
143
+
144
+ json.each do |job|
145
+ job.each_pair do |k, v|
146
+ next unless v.is_a? Numeric
147
+
148
+ report(
149
+ host: uri.host,
150
+ service: "chronos job #{job['name']} #{k}",
151
+ metric: v,
152
+ ttl: 120,
153
+ )
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ Riemann::Tools::Chronos.run
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Kyle Kingsbury
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,10 @@
1
+ # Riemann Docker
2
+
3
+ Gathers Docker container metrics and sends them to Riemann.
4
+
5
+ # Getting started
6
+
7
+ ```
8
+ gem install riemann-docker
9
+ riemann-docker --help
10
+ ```
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'rubygems/package_task'
5
+ require 'rdoc/task'
6
+ require 'find'
7
+
8
+ # Don't include resource forks in tarballs on Mac OS X.
9
+ ENV['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
10
+ ENV['COPYFILE_DISABLE'] = 'true'
11
+
12
+ # Gemspec
13
+ gemspec = Gem::Specification.new do |s|
14
+ s.rubyforge_project = 'riemann-docker'
15
+
16
+ s.name = 'riemann-docker'
17
+ s.version = '0.1.3'
18
+ s.author = 'Shani Elharrar'
19
+ s.email = ''
20
+ s.homepage = 'https://github.com/riemann/riemann-tools'
21
+ s.platform = Gem::Platform::RUBY
22
+ s.summary = 'Submits Docker container stats to riemann.'
23
+ s.license = 'MIT'
24
+
25
+ s.add_dependency 'riemann-tools', '>= 0.2.13'
26
+ s.add_dependency 'docker-api', '>= 1.22.0'
27
+
28
+ s.files = FileList['bin/*', 'LICENSE', 'README.md'].to_a
29
+ s.executables |= Dir.entries('bin/')
30
+ s.has_rdoc = false
31
+
32
+ s.required_ruby_version = '>= 1.8.7'
33
+ end
34
+
35
+ Gem::PackageTask.new gemspec do |p|
36
+ end