riemann-tools 1.10.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +7 -6
- data/.gitignore +1 -0
- data/.rubocop.yml +18 -0
- data/CHANGELOG.md +23 -0
- data/Gemfile +22 -0
- data/Rakefile +1 -1
- data/bin/riemann-hwmon +8 -0
- data/bin/riemann-tls-check +8 -0
- data/lib/riemann/tools/apache_status.rb +2 -0
- data/lib/riemann/tools/bench.rb +4 -2
- data/lib/riemann/tools/consul_health.rb +2 -0
- data/lib/riemann/tools/dir_files_count.rb +2 -0
- data/lib/riemann/tools/dir_space.rb +2 -0
- data/lib/riemann/tools/diskstats.rb +6 -4
- data/lib/riemann/tools/fd.rb +2 -0
- data/lib/riemann/tools/freeswitch.rb +2 -0
- data/lib/riemann/tools/haproxy.rb +2 -0
- data/lib/riemann/tools/health.rb +79 -11
- data/lib/riemann/tools/http_check.rb +56 -17
- data/lib/riemann/tools/hwmon.rb +111 -0
- data/lib/riemann/tools/mdstat_parser.tab.rb +4 -2
- data/lib/riemann/tools/net.rb +3 -7
- data/lib/riemann/tools/nginx_status.rb +8 -4
- data/lib/riemann/tools/ntp.rb +2 -0
- data/lib/riemann/tools/portcheck.rb +2 -0
- data/lib/riemann/tools/proc.rb +2 -0
- data/lib/riemann/tools/tls_check.rb +604 -0
- data/lib/riemann/tools/utils.rb +39 -0
- data/lib/riemann/tools/varnish.rb +2 -0
- data/lib/riemann/tools/version.rb +1 -1
- data/lib/riemann/tools.rb +26 -9
- data/riemann-tools.gemspec +2 -11
- data/tools/riemann-aws/lib/riemann/tools/aws/billing.rb +3 -1
- data/tools/riemann-aws/lib/riemann/tools/aws/rds_status.rb +2 -0
- data/tools/riemann-aws/lib/riemann/tools/aws/s3_status.rb +1 -1
- data/tools/riemann-aws/lib/riemann/tools/aws/sqs_status.rb +2 -0
- data/tools/riemann-aws/lib/riemann/tools/aws/status.rb +11 -9
- data/tools/riemann-chronos/lib/riemann/tools/chronos.rb +2 -0
- data/tools/riemann-docker/lib/riemann/tools/docker.rb +5 -5
- data/tools/riemann-marathon/lib/riemann/tools/marathon.rb +2 -0
- data/tools/riemann-munin/lib/riemann/tools/munin.rb +2 -0
- data/tools/riemann-rabbitmq/lib/riemann/tools/rabbitmq.rb +7 -7
- data/tools/riemann-riak/lib/riemann/tools/riak.rb +4 -2
- metadata +10 -129
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa81e2c6ea617e2450bdc8456f8665493241b19256be9a5443b6351e5d417ace
|
4
|
+
data.tar.gz: 0eb2bb5e1f6caea452a2babe933acd270840a78fe15520d637b7b3eb1deeb93e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eccb9331a24c1db7812365ee6c52d811a962b681563237f1e4f196aad7ae59171daaf9548db8792ff8ab548b393a04c00078c8ba59701373f8c452077960cae6
|
7
|
+
data.tar.gz: 75508745d0f31fd2b5457531ae68158f514ca5ac9fa65c64c00c9ceedf67df8644b87bd324ef0aca94527e862c51ad063702ab8be95181723b6c73fefd2c9fb9
|
data/.github/workflows/ci.yml
CHANGED
@@ -17,7 +17,7 @@ jobs:
|
|
17
17
|
- name: Setup ruby
|
18
18
|
uses: ruby/setup-ruby@v1
|
19
19
|
with:
|
20
|
-
ruby-version: '
|
20
|
+
ruby-version: '3.1'
|
21
21
|
bundler-cache: true
|
22
22
|
- name: Run rubocop
|
23
23
|
run: bundle exec rubocop
|
@@ -27,11 +27,12 @@ jobs:
|
|
27
27
|
strategy:
|
28
28
|
matrix:
|
29
29
|
ruby-version:
|
30
|
-
- 2.6
|
31
|
-
- 2.7
|
32
|
-
- 3.0
|
33
|
-
- 3.1
|
34
|
-
- 3.2
|
30
|
+
- '2.6'
|
31
|
+
- '2.7'
|
32
|
+
- '3.0'
|
33
|
+
- '3.1'
|
34
|
+
- '3.2'
|
35
|
+
- '3.3'
|
35
36
|
steps:
|
36
37
|
- uses: actions/checkout@v4
|
37
38
|
- name: Setup Ruby
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
---
|
2
2
|
AllCops:
|
3
|
+
NewCops: enable
|
3
4
|
Exclude:
|
4
5
|
- lib/riemann/tools/*_parser.tab.rb
|
5
6
|
- vendor/bundle/**/*
|
7
|
+
require:
|
8
|
+
- rubocop-rake
|
9
|
+
- rubocop-rspec
|
6
10
|
Gemspec/RequiredRubyVersion:
|
7
11
|
Enabled: false
|
8
12
|
Layout/HashAlignment:
|
9
13
|
EnforcedHashRocketStyle: table
|
10
14
|
Layout/LineLength:
|
11
15
|
Enabled: false
|
16
|
+
Lint/EmptyBlock:
|
17
|
+
Enabled: false
|
12
18
|
Metrics/AbcSize:
|
13
19
|
Enabled: false
|
14
20
|
Metrics/BlockLength:
|
@@ -28,10 +34,22 @@ Naming/MethodParameterName:
|
|
28
34
|
- az # availability zone
|
29
35
|
- id
|
30
36
|
- lb # load balancer
|
37
|
+
RSpec/ExampleLength:
|
38
|
+
Enabled: false
|
39
|
+
RSpec/MultipleExpectations:
|
40
|
+
Enabled: false
|
41
|
+
RSpec/NamedSubject:
|
42
|
+
Enabled: false
|
43
|
+
RSpec/NestedGroups:
|
44
|
+
Enabled: false
|
45
|
+
RSpec/SubjectStub:
|
46
|
+
Enabled: false
|
31
47
|
Style/Documentation:
|
32
48
|
Enabled: false
|
33
49
|
Style/HashSyntax:
|
34
50
|
EnforcedShorthandSyntax: never
|
51
|
+
Style/NegatedIfElseCondition:
|
52
|
+
Enabled: false
|
35
53
|
Style/TrailingCommaInArguments:
|
36
54
|
EnforcedStyleForMultiline: consistent_comma
|
37
55
|
Style/TrailingCommaInArrayLiteral:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.11.0](https://github.com/riemann/riemann-tools/tree/v1.11.0) (2024-07-07)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.10.0...v1.11.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Add a new `riemann-hwmon` tool for harware monitors [\#297](https://github.com/riemann/riemann-tools/pull/297) ([smortex](https://github.com/smortex))
|
10
|
+
- Add support for ignoring IPs by ASN in `riemann-http` [\#295](https://github.com/riemann/riemann-tools/pull/295) ([smortex](https://github.com/smortex))
|
11
|
+
- Add support for a minimum TTL for events [\#294](https://github.com/riemann/riemann-tools/pull/294) ([smortex](https://github.com/smortex))
|
12
|
+
- Detect and report stray arguments [\#293](https://github.com/riemann/riemann-tools/pull/293) ([smortex](https://github.com/smortex))
|
13
|
+
- Add leniency to disk thresholds of `riemann-health` [\#282](https://github.com/riemann/riemann-tools/pull/282) ([smortex](https://github.com/smortex))
|
14
|
+
- Add `riemann-tls-check` to monitor TLS certificates [\#253](https://github.com/riemann/riemann-tools/pull/253) ([smortex](https://github.com/smortex))
|
15
|
+
|
16
|
+
**Fixed bugs:**
|
17
|
+
|
18
|
+
- Minor `riemann-hwmon` improvements [\#298](https://github.com/riemann/riemann-tools/pull/298) ([smortex](https://github.com/smortex))
|
19
|
+
- Fix `riemann-nginx` checks selection [\#292](https://github.com/riemann/riemann-tools/pull/292) ([smortex](https://github.com/smortex))
|
20
|
+
- Fix `riemann-health` memory reporting when using ZFS on Linux [\#289](https://github.com/riemann/riemann-tools/pull/289) ([smortex](https://github.com/smortex))
|
21
|
+
|
22
|
+
**Closed issues:**
|
23
|
+
|
24
|
+
- RFC: `riemann-domain-check` to monitor domain name expiration date [\#249](https://github.com/riemann/riemann-tools/issues/249)
|
25
|
+
|
3
26
|
## [v1.10.0](https://github.com/riemann/riemann-tools/tree/v1.10.0) (2024-01-13)
|
4
27
|
|
5
28
|
[Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.9.1...v1.10.0)
|
data/Gemfile
CHANGED
@@ -4,3 +4,25 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in riemann-tools.gemspec
|
6
6
|
gemspec
|
7
|
+
|
8
|
+
gem 'github_changelog_generator'
|
9
|
+
gem 'maxmind-geoip2'
|
10
|
+
gem 'racc'
|
11
|
+
gem 'rake'
|
12
|
+
gem 'rspec'
|
13
|
+
gem 'rubocop'
|
14
|
+
gem 'rubocop-rake'
|
15
|
+
gem 'rubocop-rspec'
|
16
|
+
gem 'sinatra'
|
17
|
+
gem 'webrick'
|
18
|
+
|
19
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
|
20
|
+
# XXX: Needed for Ruby 2.6 compatibility
|
21
|
+
#
|
22
|
+
# With Ruby 2.6 an older version of rakup is installed that cause other gems
|
23
|
+
# to be installed with a legacy version.
|
24
|
+
#
|
25
|
+
# Because rakup is only needed when using rack 3, we can just ignore this
|
26
|
+
# with Ruby 2.6.
|
27
|
+
gem 'rackup'
|
28
|
+
end
|
data/Rakefile
CHANGED
data/bin/riemann-hwmon
ADDED
@@ -18,6 +18,8 @@ module Riemann
|
|
18
18
|
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
19
|
|
20
20
|
def initialize
|
21
|
+
super
|
22
|
+
|
21
23
|
@uri = URI.parse("#{opts[:uri]}?auto")
|
22
24
|
# Sample Response with ExtendedStatus On
|
23
25
|
# Total Accesses: 20643
|
data/lib/riemann/tools/bench.rb
CHANGED
@@ -11,6 +11,8 @@ module Riemann
|
|
11
11
|
attr_accessor :client, :hosts, :services, :states
|
12
12
|
|
13
13
|
def initialize
|
14
|
+
super
|
15
|
+
|
14
16
|
@hosts = [nil] + (0...10).map { |i| "host#{i}" }
|
15
17
|
@hosts = %w[a b c d e f g h i j]
|
16
18
|
@services = %w[test1 test2 test3 foo bar baz xyzzy attack cat treat]
|
@@ -19,8 +21,8 @@ module Riemann
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def evolve(state)
|
22
|
-
m = state[:metric] + (rand - 0.5) * 0.1
|
23
|
-
m =
|
24
|
+
m = state[:metric] + ((rand - 0.5) * 0.1)
|
25
|
+
m = m.clamp(0, 1)
|
24
26
|
|
25
27
|
s = case m
|
26
28
|
when 0...0.75
|
@@ -20,6 +20,8 @@ module Riemann
|
|
20
20
|
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)"
|
21
21
|
|
22
22
|
def initialize
|
23
|
+
super
|
24
|
+
|
23
25
|
@hostname = opts[:consul_host]
|
24
26
|
@prefix = opts[:prefix]
|
25
27
|
@minimum_services_per_node = opts[:minimum_services_per_node]
|
@@ -15,6 +15,8 @@ module Riemann
|
|
15
15
|
opt :alert_on_missing, 'Send a critical metric if the directory is missing?', default: true
|
16
16
|
|
17
17
|
def initialize
|
18
|
+
super
|
19
|
+
|
18
20
|
@dir = opts.fetch(:directory)
|
19
21
|
@service_prefix = opts.fetch(:service_prefix)
|
20
22
|
@warning = opts.fetch(:warning, nil)
|
@@ -15,6 +15,8 @@ module Riemann
|
|
15
15
|
opt :alert_on_missing, 'Send a critical metric if the directory is missing?', default: true
|
16
16
|
|
17
17
|
def initialize
|
18
|
+
super
|
19
|
+
|
18
20
|
@dir = opts.fetch(:directory)
|
19
21
|
@service_prefix = opts.fetch(:service_prefix)
|
20
22
|
@warning = opts.fetch(:warning, nil)
|
@@ -11,12 +11,14 @@ module Riemann
|
|
11
11
|
opt :ignore_devices, 'Devices to ignore', type: :strings, default: nil
|
12
12
|
|
13
13
|
def initialize
|
14
|
+
super
|
15
|
+
|
14
16
|
@old_state = nil
|
15
17
|
end
|
16
18
|
|
17
19
|
def state
|
18
20
|
f = File.read('/proc/diskstats')
|
19
|
-
state = f.split("\n").
|
21
|
+
state = f.split("\n").grep_v(/(ram|loop)/).each_with_object({}) do |line, s|
|
20
22
|
next unless line =~ /^(?:\s+\d+){2}\s+([\w\d-]+) (.*)$/
|
21
23
|
|
22
24
|
dev = Regexp.last_match(1)
|
@@ -43,13 +45,13 @@ module Riemann
|
|
43
45
|
# Filter interfaces
|
44
46
|
if (is = opts[:devices])
|
45
47
|
state = state.select do |service, _value|
|
46
|
-
is.include? service.split
|
48
|
+
is.include? service.split.first
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
52
|
if (ign = opts[:ignore_devices])
|
51
53
|
state = state.reject do |service, _value|
|
52
|
-
ign.include? service.split
|
54
|
+
ign.include? service.split.first
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
@@ -80,7 +82,7 @@ module Riemann
|
|
80
82
|
next unless service =~ /io time$/
|
81
83
|
|
82
84
|
report(
|
83
|
-
service: "diskstats #{service.gsub(
|
85
|
+
service: "diskstats #{service.gsub('time', 'util')}",
|
84
86
|
metric: (delta.to_f / (opts[:interval] * 1000)),
|
85
87
|
state: 'ok',
|
86
88
|
)
|
data/lib/riemann/tools/fd.rb
CHANGED
@@ -16,6 +16,8 @@ module Riemann
|
|
16
16
|
opt :processes, 'list of processes to measure fd usage in addition to system total', type: :ints
|
17
17
|
|
18
18
|
def initialize
|
19
|
+
super
|
20
|
+
|
19
21
|
@limits = {
|
20
22
|
fd: { critical: opts[:fd_sys_critical], warning: opts[:fd_sys_warning] },
|
21
23
|
process: { critical: opts[:fd_proc_critical], warning: opts[:fd_proc_warning] },
|
@@ -16,6 +16,8 @@ module Riemann
|
|
16
16
|
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
17
|
|
18
18
|
def initialize
|
19
|
+
super
|
20
|
+
|
19
21
|
@uri = URI("#{opts[:stats_url]};csv")
|
20
22
|
end
|
21
23
|
|
data/lib/riemann/tools/health.rb
CHANGED
@@ -11,10 +11,15 @@ module Riemann
|
|
11
11
|
include Riemann::Tools
|
12
12
|
include Riemann::Tools::Utils
|
13
13
|
|
14
|
+
PROC_PID_INIT_INO = 0xEFFFFFFC
|
15
|
+
SI_UNITS = '_kMGTPEZYRQ'
|
16
|
+
|
14
17
|
opt :cpu_warning, 'CPU warning threshold (fraction of total jiffies)', default: 0.9
|
15
18
|
opt :cpu_critical, 'CPU critical threshold (fraction of total jiffies)', default: 0.95
|
16
19
|
opt :disk_warning, 'Disk warning threshold (fraction of space used)', default: 0.9
|
17
20
|
opt :disk_critical, 'Disk critical threshold (fraction of space used)', default: 0.95
|
21
|
+
opt :disk_warning_leniency, 'Disk warning threshold (amount of free space)', short: :none, default: '500G'
|
22
|
+
opt :disk_critical_leniency, 'Disk critical threshold (amount of free space)', short: :none, default: '250G'
|
18
23
|
opt :disk_ignorefs, 'A list of filesystem types to ignore',
|
19
24
|
default: %w[anon_inodefs autofs cd9660 devfs devtmpfs fdescfs iso9660 linprocfs linsysfs nfs overlay procfs squashfs tmpfs]
|
20
25
|
opt :load_warning, 'Load warning threshold (load average / core)', default: 3.0
|
@@ -30,9 +35,11 @@ module Riemann
|
|
30
35
|
opt :checks, 'A list of checks to run.', type: :strings, default: %w[cpu load memory disk swap]
|
31
36
|
|
32
37
|
def initialize
|
38
|
+
super
|
39
|
+
|
33
40
|
@limits = {
|
34
41
|
cpu: { critical: opts[:cpu_critical], warning: opts[:cpu_warning] },
|
35
|
-
disk: { critical: opts[:disk_critical], warning: opts[:disk_warning] },
|
42
|
+
disk: { critical: opts[:disk_critical], warning: opts[:disk_warning], critical_leniency_kb: human_size_to_number(opts[:disk_critical_leniency]) / 1024, warning_leniency_kb: human_size_to_number(opts[:disk_warning_leniency]) / 1024 },
|
36
43
|
load: { critical: opts[:load_critical], warning: opts[:load_warning] },
|
37
44
|
memory: { critical: opts[:memory_critical], warning: opts[:memory_warning] },
|
38
45
|
uptime: { critical: opts[:uptime_critical], warning: opts[:uptime_warning] },
|
@@ -154,6 +161,11 @@ module Riemann
|
|
154
161
|
end
|
155
162
|
end
|
156
163
|
|
164
|
+
def linux_running_in_container?
|
165
|
+
@linux_running_in_container = File.readlink('/proc/self/ns/pid') != "pid:[#{PROC_PID_INIT_INO}]" if @linux_running_in_container.nil?
|
166
|
+
@linux_running_in_container
|
167
|
+
end
|
168
|
+
|
157
169
|
def linux_cpu
|
158
170
|
new = File.read('/proc/stat')
|
159
171
|
unless new[/cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/]
|
@@ -188,19 +200,50 @@ module Riemann
|
|
188
200
|
end
|
189
201
|
|
190
202
|
def linux_memory
|
191
|
-
m = File.read('/proc/meminfo').split(
|
203
|
+
m = File.read('/proc/meminfo').split("\n").each_with_object({}) do |line, info|
|
192
204
|
x = line.split(/:?\s+/)
|
193
205
|
# Assume kB...
|
194
206
|
info[x[0]] = x[1].to_i
|
195
207
|
end
|
196
208
|
|
197
|
-
free = m['MemFree']
|
198
|
-
total = m['MemTotal']
|
209
|
+
free = m['MemFree'] + m['Buffers'] + m['Cached'] + linux_zfs_arc_evictable_memory
|
210
|
+
total = m['MemTotal']
|
199
211
|
fraction = 1 - (free.to_f / total)
|
200
212
|
|
201
213
|
report_pct :memory, fraction, "used\n\n#{reverse_numeric_sort_with_header(`ps -eo pmem,pid,comm`)}"
|
202
214
|
end
|
203
215
|
|
216
|
+
# On Linux, the ZFS ARC is reported as used, not as cached memory.
|
217
|
+
# https://github.com/openzfs/zfs/issues/10251
|
218
|
+
#
|
219
|
+
# Gather ZFS ARC statisticts about evictable memory. The available
|
220
|
+
# fields are listed here:
|
221
|
+
# https://github.com/openzfs/zfs/blob/master/include/sys/arc_impl.h
|
222
|
+
def linux_zfs_arc_evictable_memory
|
223
|
+
# When the system is a container, it can access the hosts stats that
|
224
|
+
# cause invalid memory usage reporting. We should only remove
|
225
|
+
# evictable memory from the ZFS ARC on the host system.
|
226
|
+
return 0 if linux_running_in_container?
|
227
|
+
|
228
|
+
m = File.readlines('/proc/spl/kstat/zfs/arcstats').each_with_object(Hash.new(0)) do |line, info|
|
229
|
+
x = line.split(/\s+/)
|
230
|
+
info[x[0]] = x[2].to_i
|
231
|
+
end
|
232
|
+
|
233
|
+
(
|
234
|
+
m['anon_evictable_data'] +
|
235
|
+
m['anon_evictable_metadata'] +
|
236
|
+
m['mru_evictable_data'] +
|
237
|
+
m['mru_evictable_metadata'] +
|
238
|
+
m['mfu_evictable_data'] +
|
239
|
+
m['mfu_evictable_metadata'] +
|
240
|
+
m['uncached_evictable_data'] +
|
241
|
+
m['uncached_evictable_metadata']
|
242
|
+
) / 1024 # We want kB...
|
243
|
+
rescue Errno::ENOENT
|
244
|
+
0
|
245
|
+
end
|
246
|
+
|
204
247
|
def freebsd_cpu
|
205
248
|
u2, n2, s2, t2, i2 = `sysctl -n kern.cp_time 2>/dev/null`.split.map(&:to_i) # FreeBSD has 5 cpu stats
|
206
249
|
|
@@ -374,14 +417,14 @@ module Riemann
|
|
374
417
|
def df
|
375
418
|
case @ostype
|
376
419
|
when 'darwin', 'freebsd', 'openbsd'
|
377
|
-
`df -
|
420
|
+
`df -Pk -t no#{opts[:disk_ignorefs].join(',')}`
|
378
421
|
when 'sunos'
|
379
|
-
`df -
|
422
|
+
`df -Pk` # Is there a good way to exlude iso9660 here?
|
380
423
|
else
|
381
424
|
if @supports_exclude_type
|
382
|
-
`df -
|
425
|
+
`df -Pk #{opts[:disk_ignorefs].map { |fstype| "--exclude-type=#{fstype}" }.join(' ')}`
|
383
426
|
else
|
384
|
-
`df -
|
427
|
+
`df -Pk`
|
385
428
|
end
|
386
429
|
end
|
387
430
|
end
|
@@ -397,12 +440,12 @@ module Riemann
|
|
397
440
|
|
398
441
|
x = used.to_f / total_without_reservation
|
399
442
|
|
400
|
-
if x > @limits[:disk][:critical]
|
443
|
+
if x > @limits[:disk][:critical] && available < @limits[:disk][:critical_leniency_kb]
|
401
444
|
alert "disk #{f[5]}", :critical, x, "#{f[4]} used"
|
402
|
-
elsif x > @limits[:disk][:warning]
|
445
|
+
elsif x > @limits[:disk][:warning] && available < @limits[:disk][:warning_leniency_kb]
|
403
446
|
alert "disk #{f[5]}", :warning, x, "#{f[4]} used"
|
404
447
|
else
|
405
|
-
alert "disk #{f[5]}", :ok, x, "#{f[4]} used"
|
448
|
+
alert "disk #{f[5]}", :ok, x, "#{f[4]} used, #{number_to_human_size(available * 1024, :floor)} free"
|
406
449
|
end
|
407
450
|
end
|
408
451
|
end
|
@@ -468,6 +511,31 @@ module Riemann
|
|
468
511
|
].compact.join(' ')
|
469
512
|
end
|
470
513
|
|
514
|
+
def human_size_to_number(value)
|
515
|
+
case value
|
516
|
+
when /^\d+$/ then value.to_i
|
517
|
+
when /^\d+k$/i then value.to_i * 1024
|
518
|
+
when /^\d+M$/i then value.to_i * (1024**2)
|
519
|
+
when /^\d+G$/i then value.to_i * (1024**3)
|
520
|
+
when /^\d+T$/i then value.to_i * (1024**4)
|
521
|
+
when /^\d+P$/i then value.to_i * (1024**5)
|
522
|
+
when /^\d+E$/i then value.to_i * (1024**6)
|
523
|
+
when /^\d+Z$/i then value.to_i * (1024**7)
|
524
|
+
when /^\d+Y$/i then value.to_i * (1024**8)
|
525
|
+
when /^\d+R$/i then value.to_i * (1024**9)
|
526
|
+
when /^\d+Q$/i then value.to_i * (1024**10)
|
527
|
+
else
|
528
|
+
raise %(Malformed size "#{value}", syntax is [0-9]+[#{SI_UNITS[1..]}]?)
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
def number_to_human_size(value, rounding = :round)
|
533
|
+
return value.to_s if value < 1024
|
534
|
+
|
535
|
+
r = Math.log(value, 1024).floor
|
536
|
+
format('%<size>.1f%<unit>ciB', size: (value.to_f / (1024**r)).send(rounding, 1), unit: SI_UNITS[r])
|
537
|
+
end
|
538
|
+
|
471
539
|
def tick
|
472
540
|
invalidate_cache
|
473
541
|
|
@@ -32,15 +32,24 @@ module Riemann
|
|
32
32
|
opt :resolvers, 'Run this number of resolver threads', short: :none, type: :integer, default: 5
|
33
33
|
opt :workers, 'Run this number of worker threads', short: :none, type: :integer, default: 20
|
34
34
|
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)"
|
35
|
+
opt :ignored_asn, 'Ignore addresses belonging to these ASN', short: :none, type: :integers, default: []
|
36
|
+
opt :geoip_asn_database, 'Path to the GeoIP ASN database', short: :none, default: '/usr/share/GeoIP/GeoLite2-ASN.mmdb'
|
35
37
|
|
36
38
|
def initialize
|
39
|
+
super
|
40
|
+
|
37
41
|
@resolve_queue = Queue.new
|
38
42
|
@work_queue = Queue.new
|
39
43
|
|
44
|
+
@resolvers = []
|
45
|
+
@workers = []
|
46
|
+
|
40
47
|
opts[:resolvers].times do
|
41
|
-
Thread.new do
|
48
|
+
@resolvers << Thread.new do
|
42
49
|
loop do
|
43
50
|
uri = @resolve_queue.pop
|
51
|
+
Thread.exit unless uri
|
52
|
+
|
44
53
|
host = uri.host
|
45
54
|
|
46
55
|
addresses = Resolv::DNS.new.getaddresses(host)
|
@@ -53,21 +62,61 @@ module Riemann
|
|
53
62
|
end
|
54
63
|
end
|
55
64
|
|
65
|
+
if opts[:ignored_asn].any?
|
66
|
+
addresses.reject! do |address|
|
67
|
+
address_belongs_to_ignored_asn?(address)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
next if addresses.empty?
|
72
|
+
|
56
73
|
@work_queue.push([uri, addresses])
|
57
74
|
end
|
58
75
|
end
|
59
76
|
end
|
60
77
|
|
61
78
|
opts[:workers].times do
|
62
|
-
Thread.new do
|
79
|
+
@workers << Thread.new do
|
63
80
|
loop do
|
64
81
|
uri, addresses = @work_queue.pop
|
82
|
+
Thread.exit unless uri
|
83
|
+
|
65
84
|
test_uri_addresses(uri, addresses)
|
66
85
|
end
|
67
86
|
end
|
68
87
|
end
|
88
|
+
end
|
69
89
|
|
70
|
-
|
90
|
+
def address_belongs_to_ignored_asn?(address)
|
91
|
+
begin
|
92
|
+
require 'maxmind/geoip2'
|
93
|
+
rescue LoadError
|
94
|
+
raise StandardError, 'MaxMind::GeoIP2 is not available. Please install the maxmind-geoip2 gem for filtering by ASN.'
|
95
|
+
end
|
96
|
+
|
97
|
+
@reader ||= MaxMind::GeoIP2::Reader.new(database: opts[:geoip_asn_database])
|
98
|
+
asn = @reader.asn(address.to_s)
|
99
|
+
|
100
|
+
opts[:ignored_asn].include?(asn&.autonomous_system_number)
|
101
|
+
rescue MaxMind::GeoIP2::AddressNotFoundError
|
102
|
+
false
|
103
|
+
end
|
104
|
+
|
105
|
+
# Under normal operation, we have a single instance of this class for the
|
106
|
+
# lifetime of the process. But when testing, we create a new instance
|
107
|
+
# for each test, each with its resolvers and worker threads. The test
|
108
|
+
# process may end-up with a lot of running threads, hitting the OS limit
|
109
|
+
# of max threads by process and being unable to create more thread:
|
110
|
+
#
|
111
|
+
# ThreadError: can't create Thread: Resource temporarily unavailable
|
112
|
+
#
|
113
|
+
# To avoid this situation, we provide this method.
|
114
|
+
def shutdown
|
115
|
+
@resolve_queue.close
|
116
|
+
@resolvers.map(&:join)
|
117
|
+
|
118
|
+
@work_queue.close
|
119
|
+
@workers.map(&:join)
|
71
120
|
end
|
72
121
|
|
73
122
|
def tick
|
@@ -104,10 +153,8 @@ module Riemann
|
|
104
153
|
def test_uri_addresses(uri, addresses)
|
105
154
|
request = get_request(uri)
|
106
155
|
|
107
|
-
responses =
|
108
|
-
|
109
|
-
addresses.each do |address|
|
110
|
-
responses << test_uri_address(uri, address.to_s, request)
|
156
|
+
responses = addresses.map do |address|
|
157
|
+
test_uri_address(uri, address.to_s, request)
|
111
158
|
end
|
112
159
|
|
113
160
|
responses.compact!
|
@@ -265,8 +312,8 @@ module Riemann
|
|
265
312
|
end
|
266
313
|
|
267
314
|
def latency_state(name, latency)
|
268
|
-
critical_threshold = opts["#{name}_latency_critical"
|
269
|
-
warning_threshold = opts["#{name}_latency_warning"
|
315
|
+
critical_threshold = opts[:"#{name}_latency_critical"]
|
316
|
+
warning_threshold = opts[:"#{name}_latency_warning"]
|
270
317
|
|
271
318
|
return if critical_threshold.zero? || warning_threshold.zero?
|
272
319
|
|
@@ -301,14 +348,6 @@ module Riemann
|
|
301
348
|
reported_uri.password = '**redacted**' if reported_uri.password
|
302
349
|
reported_uri
|
303
350
|
end
|
304
|
-
|
305
|
-
def endpoint_name(address, port)
|
306
|
-
if address.ipv6?
|
307
|
-
"[#{address}]:#{port}"
|
308
|
-
else
|
309
|
-
"#{address}:#{port}"
|
310
|
-
end
|
311
|
-
end
|
312
351
|
end
|
313
352
|
end
|
314
353
|
end
|