riemann-tools 1.6.0 → 1.7.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 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: []