riemann-tools 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e201bab60a1f457d506ec890d20bbda78e7229fba76acbae599b85c7d366a07b
4
- data.tar.gz: 522750b32f5002d8fd799f95a4686eb576d63723781269fb489dd23da5567c22
3
+ metadata.gz: ad07110215b87b2b1128127294c855149bbdd0e96623c8aaaedfc7b34434994c
4
+ data.tar.gz: 5957f98f865a20456a063a72e293e1af2a8dfa73d7a898fb319e1485853c5313
5
5
  SHA512:
6
- metadata.gz: 7e1634227dddcdd7f4223489f1193ab45168572143fae011790bc811ec346cb21743722b5a068337f8a612a0c20ea76769f7af739d74c242a9d043ec8749b625
7
- data.tar.gz: 0c761697583bd243ea1788877a63ea21decdb25012bd52d59e109165e2e76efde3c11299c60b81aa8a0442fb3482957f06539074ea5cb56fb1d5b698994ddf11
6
+ metadata.gz: 51b9c2da5e9cc9e334903c53e086e9df1dac212dc57d5fd02d9dc234a842296eaaf433eb99b787dd618b2fa839969a44b0e2da5ede1a2b4fcc0bfb2251cbf5fb
7
+ data.tar.gz: a5904b787d46c07d16a581a37fc3c2561c96c858d475d4e855e3119294464f6a530a5f5e885b3910660b9678a15e085183eaefcef6ae268b2dcc5c253e18fbd0
@@ -31,6 +31,7 @@ jobs:
31
31
  - 2.7
32
32
  - 3.0
33
33
  - 3.1
34
+ - 3.2
34
35
  steps:
35
36
  - uses: actions/checkout@v3
36
37
  - name: Setup Ruby
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.7.0](https://github.com/riemann/riemann-tools/tree/v1.7.0) (2023-01-11)
4
+
5
+ [Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.6.0...v1.7.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Override default HTTP User-Agent and make it tuneable [\#257](https://github.com/riemann/riemann-tools/pull/257) ([smortex](https://github.com/smortex))
10
+ - Allow opting out of `riemann-http-check` latency state [\#255](https://github.com/riemann/riemann-tools/pull/255) ([smortex](https://github.com/smortex))
11
+ - Speed-up `riemann-http-check` with resolver and worker threads [\#254](https://github.com/riemann/riemann-tools/pull/254) ([smortex](https://github.com/smortex))
12
+ - Allow mdstat device filtering [\#252](https://github.com/riemann/riemann-tools/pull/252) ([smortex](https://github.com/smortex))
13
+ - Report mdstat health by device [\#251](https://github.com/riemann/riemann-tools/pull/251) ([smortex](https://github.com/smortex))
14
+
15
+ **Fixed bugs:**
16
+
17
+ - Fix `riemann-http-check` with unresolvable domains [\#256](https://github.com/riemann/riemann-tools/pull/256) ([smortex](https://github.com/smortex))
18
+
3
19
  ## [v1.6.0](https://github.com/riemann/riemann-tools/tree/v1.6.0) (2022-11-04)
4
20
 
5
21
  [Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.5.0...v1.6.0)
@@ -14,9 +14,10 @@ module Riemann
14
14
  require 'uri'
15
15
 
16
16
  opt :uri, 'Apache Server Status URI', default: 'http://localhost/server-status'
17
+ opt :user_agent, 'User-Agent header for HTTP requests', short: :none, default: "#{File.basename($PROGRAM_NAME)}/#{Riemann::Tools::VERSION} (+https://github.com/riemann/riemann-tools)"
17
18
 
18
19
  def initialize
19
- @uri = "#{URI.parse(opts[:uri])}?auto"
20
+ @uri = URI.parse("#{opts[:uri]}?auto")
20
21
  # Sample Response with ExtendedStatus On
21
22
  # Total Accesses: 20643
22
23
  # Total kBytes: 36831
@@ -68,7 +69,7 @@ module Riemann
68
69
  def connection
69
70
  response = nil
70
71
  begin
71
- response = ::Net::HTTP.get(@uri)
72
+ response = ::Net::HTTP.new(@uri.host, @uri.port).get(@uri, { 'user-agent' => opts[:user_agent] }).body
72
73
  rescue StandardError => e
73
74
  report(
74
75
  service: 'httpd health',
@@ -12,6 +12,7 @@ module Riemann
12
12
 
13
13
  opt :cloudant_username, 'Cloudant username', type: :string, required: true
14
14
  opt :cloudant_password, 'Cloudant pasword', type: :string, required: true
15
+ opt :user_agent, 'User-Agent header for HTTP requests', short: :none, default: "#{File.basename($PROGRAM_NAME)}/#{Riemann::Tools::VERSION} (+https://github.com/riemann/riemann-tools)"
15
16
 
16
17
  def tick
17
18
  json.each do |node|
@@ -46,7 +47,7 @@ module Riemann
46
47
  http = ::Net::HTTP.new('cloudant.com', 443)
47
48
  http.use_ssl = true
48
49
  http.start do |h|
49
- get = ::Net::HTTP::Get.new('/api/load_balancer')
50
+ get = ::Net::HTTP::Get.new('/api/load_balancer', { 'user-agent' => opts[:user_agent] })
50
51
  get.basic_auth opts[:cloudant_username], opts[:cloudant_password]
51
52
  h.request get
52
53
  end
@@ -16,6 +16,7 @@ module Riemann
16
16
  opt :consul_port, 'Consul API Host (default to 8500)', default: '8500'
17
17
  opt :prefix, 'prefix to use for all service names when reporting', default: 'consul '
18
18
  opt :minimum_services_per_node, 'minimum services per node (default: 0)', default: 0
19
+ opt :user_agent, 'User-Agent header for HTTP requests', short: :none, default: "#{File.basename($PROGRAM_NAME)}/#{Riemann::Tools::VERSION} (+https://github.com/riemann/riemann-tools)"
19
20
 
20
21
  def initialize
21
22
  @hostname = opts[:consul_host]
@@ -43,7 +44,7 @@ module Riemann
43
44
  end
44
45
 
45
46
  def get(url)
46
- ::Net::HTTP.get_response(url).body
47
+ ::Net::HTTP.new(url.host, url.port).get(url, { 'user-agent' => opts[:user_agent] }).body
47
48
  end
48
49
 
49
50
  def tick
@@ -17,7 +17,7 @@ module Riemann
17
17
  def state
18
18
  f = File.read('/proc/diskstats')
19
19
  state = f.split("\n").reject { |d| d =~ /(ram|loop)/ }.each_with_object({}) do |line, s|
20
- next unless line =~ /^(?:\s+\d+){2}\s+([\w\d\-]+) (.*)$/
20
+ next unless line =~ /^(?:\s+\d+){2}\s+([\w\d-]+) (.*)$/
21
21
 
22
22
  dev = Regexp.last_match(1)
23
23
 
@@ -12,6 +12,7 @@ module Riemann
12
12
 
13
13
  opt :stats_url, 'Full url to haproxy stats (eg: https://user:password@host.com:9999/stats)', required: true,
14
14
  type: :string
15
+ opt :user_agent, 'User-Agent header for HTTP requests', short: :none, default: "#{File.basename($PROGRAM_NAME)}/#{Riemann::Tools::VERSION} (+https://github.com/riemann/riemann-tools)"
15
16
 
16
17
  def initialize
17
18
  @uri = URI("#{opts[:stats_url]};csv")
@@ -45,7 +46,7 @@ module Riemann
45
46
  http = ::Net::HTTP.new(@uri.host, @uri.port)
46
47
  http.use_ssl = true if @uri.scheme == 'https'
47
48
  res = http.start do |h|
48
- get = ::Net::HTTP::Get.new(@uri.request_uri)
49
+ get = ::Net::HTTP::Get.new(@uri.request_uri, { 'user-agent' => opts[:user_agent] })
49
50
  unless @uri.userinfo.nil?
50
51
  userinfo = @uri.userinfo.split(':')
51
52
  get.basic_auth userinfo[0], userinfo[1]
@@ -26,23 +26,86 @@ module Riemann
26
26
  opt :response_latency_critical, 'Lattency critical threshold', short: :none, default: 1.0
27
27
  opt :http_timeout, 'Timeout (in seconds) for HTTP requests', short: :none, default: 5.0
28
28
  opt :checks, 'A list of checks to run.', short: :none, type: :strings, default: %w[consistency connection-latency response-code response-latency]
29
+ opt :resolvers, 'Run this number of resolver threads', short: :none, type: :integer, default: 5
30
+ opt :workers, 'Run this number of worker threads', short: :none, type: :integer, default: 20
31
+ opt :user_agent, 'User-Agent header for HTTP requests', short: :none, default: "#{File.basename($PROGRAM_NAME)}/#{Riemann::Tools::VERSION} (+https://github.com/riemann/riemann-tools)"
32
+
33
+ def initialize
34
+ @resolve_queue = Queue.new
35
+ @work_queue = Queue.new
36
+
37
+ opts[:resolvers].times do
38
+ Thread.new do
39
+ loop do
40
+ uri = @resolve_queue.pop
41
+ host = uri.host
42
+
43
+ addresses = Resolv::DNS.new.getaddresses(host)
44
+ if addresses.empty?
45
+ host = host[1...-1] if host[0] == '[' && host[-1] == ']'
46
+ begin
47
+ addresses << IPAddr.new(host)
48
+ rescue IPAddr::InvalidAddressError
49
+ # Ignore
50
+ end
51
+ end
52
+
53
+ @work_queue.push([uri, addresses])
54
+ end
55
+ end
56
+ end
57
+
58
+ opts[:workers].times do
59
+ Thread.new do
60
+ loop do
61
+ uri, addresses = @work_queue.pop
62
+ test_uri_addresses(uri, addresses)
63
+ end
64
+ end
65
+ end
66
+
67
+ super
68
+ end
29
69
 
30
70
  def tick
71
+ report(
72
+ service: 'riemann http-check resolvers utilization',
73
+ metric: (opts[:resolvers].to_f - @resolve_queue.num_waiting) / opts[:resolvers],
74
+ state: @resolve_queue.num_waiting.positive? ? 'ok' : 'critical',
75
+ tags: %w[riemann],
76
+ )
77
+ report(
78
+ service: 'riemann http-check resolvers saturation',
79
+ metric: @resolve_queue.length,
80
+ state: @resolve_queue.empty? ? 'ok' : 'critical',
81
+ tags: %w[riemann],
82
+ )
83
+ report(
84
+ service: 'riemann http-check workers utilization',
85
+ metric: (opts[:workers].to_f - @work_queue.num_waiting) / opts[:workers],
86
+ state: @work_queue.num_waiting.positive? ? 'ok' : 'critical',
87
+ tags: %w[riemann],
88
+ )
89
+ report(
90
+ service: 'riemann http-check workers saturation',
91
+ metric: @work_queue.length,
92
+ state: @work_queue.empty? ? 'ok' : 'critical',
93
+ tags: %w[riemann],
94
+ )
95
+
31
96
  opts[:uri].each do |uri|
32
- test_uri(uri)
97
+ @resolve_queue.push(URI(uri))
33
98
  end
34
99
  end
35
100
 
36
- def test_uri(uri)
37
- uri = URI(uri)
38
-
39
- request = ::Net::HTTP::Get.new(uri)
101
+ def test_uri_addresses(uri, addresses)
102
+ request = ::Net::HTTP::Get.new(uri, { 'user-agent' => opts[:user_agent] })
40
103
  request.basic_auth(uri.user, uri.password)
41
104
 
42
105
  responses = []
43
106
 
44
- with_each_address(uri.host) do |address|
45
- responses << test_uri_address(uri, address, request)
107
+ addresses.each do |address|
108
+ responses << test_uri_address(uri, address.to_s, request)
46
109
  end
47
110
 
48
111
  responses.compact!
@@ -115,18 +178,6 @@ module Riemann
115
178
  nil
116
179
  end
117
180
 
118
- def with_each_address(host, &block)
119
- addresses = Resolv::DNS.new.getaddresses(host)
120
- if addresses.empty?
121
- host = host[1...-1] if host[0] == '[' && host[-1] == ']'
122
- addresses << IPAddr.new(host)
123
- end
124
-
125
- addresses.each do |address|
126
- block.call(address.to_s)
127
- end
128
- end
129
-
130
181
  def report_http_endpoint_response_code(http, uri, response)
131
182
  return unless response
132
183
 
@@ -156,7 +207,7 @@ module Riemann
156
207
  else
157
208
  report(
158
209
  {
159
- state: 'critical',
210
+ state: latency_state(latency, nil),
160
211
  description: 'timeout',
161
212
  }.merge(endpoint_report(http, uri, "#{latency} latency")),
162
213
  )
@@ -164,9 +215,14 @@ module Riemann
164
215
  end
165
216
 
166
217
  def latency_state(name, latency)
167
- if latency > opts["#{name}_latency_critical".to_sym]
218
+ critical_threshold = opts["#{name}_latency_critical".to_sym]
219
+ warning_threshold = opts["#{name}_latency_warning".to_sym]
220
+
221
+ return if critical_threshold.zero? || warning_threshold.zero?
222
+
223
+ if latency.nil? || latency > critical_threshold
168
224
  'critical'
169
- elsif latency > opts["#{name}_latency_warning".to_sym]
225
+ elsif latency > warning_threshold
170
226
  'warning'
171
227
  else
172
228
  'ok'
@@ -8,6 +8,9 @@ module Riemann
8
8
  class Md
9
9
  include Riemann::Tools
10
10
 
11
+ opt :devices, 'Devices to monitor', type: :strings, default: []
12
+ opt :ignore_devices, 'Devices to ignore', type: :strings, default: []
13
+
11
14
  def mdstat_parser
12
15
  @mdstat_parser ||= MdstatParser.new
13
16
  end
@@ -16,13 +19,15 @@ module Riemann
16
19
  status = File.read('/proc/mdstat')
17
20
  res = mdstat_parser.parse(status)
18
21
 
19
- state = res.values.all? { |value| value =~ /\AU+\z/ } ? 'ok' : 'critical'
22
+ res.each do |device, member_status|
23
+ next unless report_device?(device)
20
24
 
21
- report(
22
- service: 'mdstat',
23
- description: status,
24
- state: state,
25
- )
25
+ report(
26
+ service: "mdstat #{device}",
27
+ description: member_status,
28
+ state: member_status =~ /\AU+\z/ ? 'ok' : 'critical',
29
+ )
30
+ end
26
31
  rescue Racc::ParseError => e
27
32
  report(
28
33
  service: 'mdstat',
@@ -36,6 +41,14 @@ module Riemann
36
41
  state: 'critical',
37
42
  )
38
43
  end
44
+
45
+ def report_device?(device)
46
+ if !opts[:devices].empty?
47
+ opts[:devices].include?(device)
48
+ else
49
+ !opts[:ignore_devices].include?(device)
50
+ end
51
+ end
39
52
  end
40
53
  end
41
54
  end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.6.0
3
+ # This file is automatically generated by Racc 1.6.2
4
4
  # from Racc grammar file "".
5
5
  #
6
6
 
@@ -22,6 +22,7 @@ module Riemann
22
22
  opt :writing_critical, 'Writing connections critical threshold', default: 0
23
23
  opt :waiting_warning, 'Waiting connections warning threshold', default: 0
24
24
  opt :waiting_critical, 'Waiting connections critical threshold', default: 0
25
+ opt :user_agent, 'User-Agent header for HTTP requests', short: :none, default: "#{File.basename($PROGRAM_NAME)}/#{Riemann::Tools::VERSION} (+https://github.com/riemann/riemann-tools)"
25
26
 
26
27
  def initialize
27
28
  @uri = URI.parse(opts[:uri])
@@ -53,7 +54,7 @@ module Riemann
53
54
  def tick
54
55
  response = nil
55
56
  begin
56
- response = ::Net::HTTP.get(@uri)
57
+ response = ::Net::HTTP.new(@uri.host, @uri.port).get(@uri, { 'user-agent' => opts[:user_agent] }).body
57
58
  rescue StandardError => e
58
59
  report(
59
60
  service: 'nginx health',
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.6.0
3
+ # This file is automatically generated by Racc 1.6.2
4
4
  # from Racc grammar file "".
5
5
  #
6
6
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Riemann
4
4
  module Tools # :nodoc:
5
- VERSION = '1.6.0'
5
+ VERSION = '1.7.0'
6
6
  end
7
7
  end
@@ -26,6 +26,8 @@ module Riemann
26
26
  opt :get_99_warning, 'FSM 99% get time warning threshold (ms)', default: 10_000
27
27
  opt :put_99_warning, 'FSM 99% put time warning threshold (ms)', default: 10_000
28
28
 
29
+ opt :user_agent, 'User-Agent header for HTTP requests', short: :none, default: "#{File.basename($PROGRAM_NAME)}/#{Riemann::Tools::VERSION} (+https://github.com/riemann/riemann-tools)"
30
+
29
31
  def initialize
30
32
  detect_features
31
33
 
@@ -38,7 +40,7 @@ module Riemann
38
40
  http.use_ssl = uri.scheme == 'https'
39
41
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
40
42
  http.start do |h|
41
- h.get opts[:stats_path]
43
+ h.get(opts[:stats_path], { 'user-agent' => opts[:user_agent] })
42
44
  end
43
45
  rescue StandardError => _e
44
46
  @httpstatus = false
@@ -168,7 +170,7 @@ module Riemann
168
170
  http.use_ssl = uri.scheme == 'https'
169
171
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl?
170
172
  res = http.start do |h|
171
- h.get opts[:stats_path]
173
+ h.get(opts[:stats_path], { 'user-agent' => opts[:user_agent] })
172
174
  end
173
175
  rescue StandardError => e
174
176
  report(
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riemann-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Kingsbury
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-04 00:00:00.000000000 Z
11
+ date: 2023-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -352,7 +352,7 @@ metadata:
352
352
  homepage_uri: https://github.com/aphyr/riemann-tools
353
353
  source_code_uri: https://github.com/aphyr/riemann-tools
354
354
  changelog_uri: https://github.com/aphyr/riemann-tools
355
- post_install_message:
355
+ post_install_message:
356
356
  rdoc_options: []
357
357
  require_paths:
358
358
  - lib
@@ -367,8 +367,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
367
367
  - !ruby/object:Gem::Version
368
368
  version: '0'
369
369
  requirements: []
370
- rubygems_version: 3.3.23
371
- signing_key:
370
+ rubygems_version: 3.2.5
371
+ signing_key:
372
372
  specification_version: 4
373
373
  summary: Utilities which submit events to Riemann.
374
374
  test_files: []