riemann-tools 1.2.0 → 1.5.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: fa8ed5841e8d5c02ee08180af284269ca1382e174a2dfd98b28de23227a44f61
4
- data.tar.gz: 3ec31579be24a493017091aaa928b6cbd091c2d578a7d577d868ac2857e7be3d
3
+ metadata.gz: ce2307f0dfeaad07e9b904c5f0edf2b0d7a586507c94e8ffb2ff9e3ccf6b3c6f
4
+ data.tar.gz: 8178becee10569b018dfdb54693cfa9e5c5a61dfe62ecdec7ca257004e2365ff
5
5
  SHA512:
6
- metadata.gz: a5554c62f5ce95494f5ed677ccd6933224121c9d227bc9318ec54bed380e0635f1140fbfc5cf8cd3e2ecc919fc267c12f8fb8c47da58345925c69c6d19c82a51
7
- data.tar.gz: a1e3a370c5a325eb6acd59c1ad23fb3efcde20f8ff467d75a84c1e52e1f7cd2cd3102d5045bb11bfd43a43f12b01c0823c2b08f6fa75fd1e33ae50818ffa0e02
6
+ metadata.gz: 7588c24abd5c87eb95ced867cc23350697ef893463e939a47c481518209a386c2b0a56e93e9d470e2fe1d9d0a78fa01d5b8d0e3f6af265d014072a00cf44570d
7
+ data.tar.gz: 54bd9df700e67ee112e856e6104018bac1ad54444533186cdd2425416fa2ab9a0939c5bfd7de5446045d4813c9a8fac5e34db9d997ea841c9665ae97f7224b95
data/.gitignore CHANGED
@@ -5,4 +5,4 @@ pkg/
5
5
  .DS_Store
6
6
  .*.swp
7
7
  *.log
8
- lib/riemann/tools/uptime_parser.tab.rb
8
+ lib/riemann/tools/*_parser.tab.rb
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  AllCops:
3
3
  Exclude:
4
- - lib/riemann/tools/uptime_parser.tab.rb
4
+ - lib/riemann/tools/*_parser.tab.rb
5
5
  - vendor/bundle/**/*
6
6
  Gemspec/RequiredRubyVersion:
7
7
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.5.0](https://github.com/riemann/riemann-tools/tree/v1.5.0) (2022-09-08)
4
+
5
+ [Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.4.0...v1.5.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Improve error reporting on parse error [\#242](https://github.com/riemann/riemann-tools/pull/242) ([smortex](https://github.com/smortex))
10
+
11
+ **Fixed bugs:**
12
+
13
+ - Fix `riemann-haproxy` HTTP response processing [\#243](https://github.com/riemann/riemann-tools/pull/243) ([ahoetker-deca](https://github.com/ahoetker-deca))
14
+ - Fix `riemann-md` parsing of mdstat when device is being checked [\#241](https://github.com/riemann/riemann-tools/pull/241) ([smortex](https://github.com/smortex))
15
+
16
+ ## [v1.4.0](https://github.com/riemann/riemann-tools/tree/v1.4.0) (2022-08-30)
17
+
18
+ [Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.3.0...v1.4.0)
19
+
20
+ **Implemented enhancements:**
21
+
22
+ - Improve zpool state reporting [\#239](https://github.com/riemann/riemann-tools/pull/239) ([smortex](https://github.com/smortex))
23
+
24
+ **Fixed bugs:**
25
+
26
+ - Fix zpool/md informational messages reporting [\#238](https://github.com/riemann/riemann-tools/pull/238) ([smortex](https://github.com/smortex))
27
+ - Fix detection of degraded zpool [\#237](https://github.com/riemann/riemann-tools/pull/237) ([smortex](https://github.com/smortex))
28
+
29
+ ## [v1.3.0](https://github.com/riemann/riemann-tools/tree/v1.3.0) (2022-08-29)
30
+
31
+ [Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.2.0...v1.3.0)
32
+
33
+ **Implemented enhancements:**
34
+
35
+ - Add support for configuration file to riemann-wrapper [\#235](https://github.com/riemann/riemann-tools/pull/235) ([smortex](https://github.com/smortex))
36
+ - Add `riemann-md` to monitor Linux RAID/md health [\#232](https://github.com/riemann/riemann-tools/pull/232) ([smortex](https://github.com/smortex))
37
+ - Add `riemann-zpool` to monitor zpool health [\#231](https://github.com/riemann/riemann-tools/pull/231) ([smortex](https://github.com/smortex))
38
+
39
+ **Fixed bugs:**
40
+
41
+ - Fix race condition in riemann-wrapper [\#233](https://github.com/riemann/riemann-tools/pull/233) ([smortex](https://github.com/smortex))
42
+
43
+ **Closed issues:**
44
+
45
+ - There is some kind of race condition in riemann-wrapper [\#230](https://github.com/riemann/riemann-tools/issues/230)
46
+
47
+ **Merged pull requests:**
48
+
49
+ - Stop riemann-wrapper if a tool raise an error [\#234](https://github.com/riemann/riemann-tools/pull/234) ([smortex](https://github.com/smortex))
50
+
3
51
  ## [v1.2.0](https://github.com/riemann/riemann-tools/tree/v1.2.0) (2022-08-17)
4
52
 
5
53
  [Full Changelog](https://github.com/riemann/riemann-tools/compare/v1.1.1...v1.2.0)
data/Rakefile CHANGED
@@ -22,8 +22,15 @@ end
22
22
 
23
23
  task build: :gen_parser
24
24
 
25
- desc 'Generate the uptime parser'
26
- task gen_parser: 'lib/riemann/tools/uptime_parser.tab.rb'
25
+ desc 'Generate parsers'
26
+ task gen_parser: [
27
+ 'lib/riemann/tools/mdstat_parser.tab.rb',
28
+ 'lib/riemann/tools/uptime_parser.tab.rb',
29
+ ]
30
+
31
+ file 'lib/riemann/tools/mdstat_parser.tab.rb' => 'lib/riemann/tools/mdstat_parser.y' do
32
+ sh 'racc -S lib/riemann/tools/mdstat_parser.y'
33
+ end
27
34
 
28
35
  file 'lib/riemann/tools/uptime_parser.tab.rb' => 'lib/riemann/tools/uptime_parser.y' do
29
36
  sh 'racc -S lib/riemann/tools/uptime_parser.y'
data/bin/riemann-md ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools/md'
7
+
8
+ Riemann::Tools::Md.run
data/bin/riemann-wrapper CHANGED
@@ -27,9 +27,10 @@ def read_flags(argv)
27
27
  res
28
28
  end
29
29
 
30
- if ARGV.empty?
30
+ def usage
31
31
  warn <<~USAGE
32
32
  usage: riemann-wrapper [common options] -- tool1 [tool1 options] [-- tool2 [tool2 options] ...]
33
+ riemann-wrapper /path/to/configuration/file.yml
33
34
 
34
35
  Run multiple Riemann tools in a single process. A single connection to
35
36
  riemann is maintained and shared for all tools, the connection flags should
@@ -47,16 +48,53 @@ if ARGV.empty?
47
48
  fd --tag=fd -- \\
48
49
  health --tag=health -- \\
49
50
  ntp --tag=ntp
51
+
52
+ 3. Same as above example, but using a configuration file (more verbose but
53
+ easier to handle when running riemann-wrapper manually of managing it
54
+ with a Configuration Management system):
55
+
56
+ cat > config.yml << EOT
57
+ ---
58
+ options: --host riemann.example.com --tcp
59
+ tools:
60
+ - name: fd
61
+ options: --tag=fd
62
+ - name: health
63
+ options: --tag=health
64
+ - name: ntp
65
+ options: --tag=ntp
66
+ EOT
67
+ riemann-wrapper config.yml
50
68
  USAGE
51
69
  exit 1
52
70
  end
53
71
 
72
+ usage if ARGV.empty?
73
+
74
+ if ARGV.size == 1
75
+ unless File.readable?(ARGV[0])
76
+ warn "Cannot open file for reading: #{ARGV[0]}"
77
+ usage
78
+ end
79
+
80
+ require 'yaml'
81
+ config = YAML.safe_load(File.read(ARGV[0]))
82
+
83
+ commandline = config['options']
84
+ config['tools'].each { |tool| commandline << " -- #{tool['name']} #{tool['options']}" }
85
+
86
+ ARGV.replace(commandline.split)
87
+ end
88
+
54
89
  argv = ARGV.dup
55
90
 
56
91
  common_argv = read_flags(argv)
57
92
 
58
93
  threads = []
59
94
 
95
+ # Terminate the whole process is some thread fail
96
+ Thread.abort_on_exception = true
97
+
60
98
  while argv.any?
61
99
  tool = argv.shift
62
100
  tool_argv = read_flags(argv)
@@ -69,7 +107,7 @@ while argv.any?
69
107
  # Force evaluation of options. This rely on ARGV and needs to be done before
70
108
  # we launch multiple threads which compete to read information from there.
71
109
  instance.options
72
- threads << Thread.new { instance.run }
110
+ threads << Thread.new(instance, &:run)
73
111
  end
74
112
 
75
113
  threads.each(&:join)
data/bin/riemann-zpool ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Process.setproctitle($PROGRAM_NAME)
5
+
6
+ require 'riemann/tools/zpool'
7
+
8
+ Riemann::Tools::Zpool.run
@@ -44,7 +44,7 @@ module Riemann
44
44
  def csv
45
45
  http = ::Net::HTTP.new(@uri.host, @uri.port)
46
46
  http.use_ssl = true if @uri.scheme == 'https'
47
- http.start do |h|
47
+ res = http.start do |h|
48
48
  get = ::Net::HTTP::Get.new(@uri.request_uri)
49
49
  unless @uri.userinfo.nil?
50
50
  userinfo = @uri.userinfo.split(':')
@@ -52,7 +52,7 @@ module Riemann
52
52
  end
53
53
  h.request get
54
54
  end
55
- CSV.parse(http.body.split('# ')[1], { headers: true })
55
+ CSV.parse(res.body.split('# ')[1], { headers: true })
56
56
  end
57
57
  end
58
58
  end
@@ -103,6 +103,8 @@ module Riemann
103
103
  @swap_enabled = true
104
104
  end
105
105
  end
106
+
107
+ invalidate_cache
106
108
  end
107
109
 
108
110
  def alert(service, state, metric, description)
@@ -139,6 +141,8 @@ module Riemann
139
141
  end
140
142
 
141
143
  def report_uptime(uptime)
144
+ return unless uptime
145
+
142
146
  description = uptime_to_human(uptime)
143
147
 
144
148
  if uptime < @limits[:uptime][:critical]
@@ -262,6 +266,13 @@ module Riemann
262
266
 
263
267
  def uptime
264
268
  @cached_data[:uptime] ||= uptime_parser.parse(`uptime`)
269
+ rescue Racc::ParseError => e
270
+ report(
271
+ service: 'uptime',
272
+ description: "Error parsing uptime: #{e.message}",
273
+ state: 'critical',
274
+ )
275
+ @cached_data[:uptime] = {}
265
276
  end
266
277
 
267
278
  def bsd_load
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'riemann/tools'
4
+ require 'riemann/tools/mdstat_parser.tab'
5
+
6
+ module Riemann
7
+ module Tools
8
+ class Md
9
+ include Riemann::Tools
10
+
11
+ def mdstat_parser
12
+ @mdstat_parser ||= MdstatParser.new
13
+ end
14
+
15
+ def tick
16
+ status = File.read('/proc/mdstat')
17
+ res = mdstat_parser.parse(status)
18
+
19
+ state = res.values.all? { |value| value =~ /\AU+\z/ } ? 'ok' : 'critical'
20
+
21
+ report(
22
+ service: 'mdstat',
23
+ description: status,
24
+ state: state,
25
+ )
26
+ rescue Racc::ParseError => e
27
+ report(
28
+ service: 'mdstat',
29
+ description: "Error parsing mdstat: #{e.message}",
30
+ state: 'critical',
31
+ )
32
+ rescue Errno::ENOENT => e
33
+ report(
34
+ service: 'mdstat',
35
+ description: e.message,
36
+ state: 'critical',
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,371 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.6.0
4
+ # from Racc grammar file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+
9
+
10
+ require 'strscan'
11
+
12
+ require 'riemann/tools/utils'
13
+
14
+ module Riemann
15
+ module Tools
16
+ class MdstatParser < Racc::Parser
17
+
18
+ module_eval(<<'...end mdstat_parser.y/module_eval...', 'mdstat_parser.y', 49)
19
+
20
+ def parse(text)
21
+ s = Utils::StringTokenizer.new(text)
22
+
23
+ until s.eos? do
24
+ case
25
+ when s.scan(/\n/) then s.push_token(nil)
26
+ when s.scan(/\s+/) then s.push_token(nil)
27
+
28
+ when s.scan(/\[=*>.*\]/) then s.push_token(:PROGRESS)
29
+ when s.scan(/%/) then s.push_token('%')
30
+ when s.scan(/,/) then s.push_token(',')
31
+ when s.scan(/:/) then s.push_token(':')
32
+ when s.scan(/</) then s.push_token('<')
33
+ when s.scan(/=/) then s.push_token('=')
34
+ when s.scan(/>/) then s.push_token('>')
35
+ when s.scan(/\(/) then s.push_token('(')
36
+ when s.scan(/\)/) then s.push_token(')')
37
+ when s.scan(/\./) then s.push_token('.')
38
+ when s.scan(/\//) then s.push_token('/')
39
+ when s.scan(/\[/) then s.push_token('[')
40
+ when s.scan(/]/) then s.push_token(']')
41
+ when s.scan(/algorithm/) then s.push_token(:ALGORITHM)
42
+ when s.scan(/bitmap/) then s.push_token(:BITMAP)
43
+ when s.scan(/blocks/) then s.push_token(:BLOCKS)
44
+ when s.scan(/check/) then s.push_token(:CHECK)
45
+ when s.scan(/chunk/) then s.push_token(:CHUNK)
46
+ when s.scan(/finish/) then s.push_token(:FINISH)
47
+ when s.scan(/level/) then s.push_token(:LEVEL)
48
+ when s.scan(/min/) then s.push_token(:MIN)
49
+ when s.scan(/pages/) then s.push_token(:PAGES)
50
+ when s.scan(/(raid([014-6]|10)|linear|multipath|faulty)\b/) then s.push_token(:PERSONALITY)
51
+ when s.scan(/Personalities/) then s.push_token(:PERSONALITIES)
52
+ when s.scan(/recovery/) then s.push_token(:RECOVERY)
53
+ when s.scan(/reshape/) then s.push_token(:RESHAPE)
54
+ when s.scan(/resync/) then s.push_token(:RESYNC)
55
+ when s.scan(/speed/) then s.push_token(:SPEED)
56
+ when s.scan(/super/) then s.push_token(:SUPER)
57
+ when s.scan(/unused devices/) then s.push_token(:UNUSED_DEVICES)
58
+ when s.scan(/K\/sec/) then s.push_token(:SPEED_UNIT)
59
+ when s.scan(/KB/) then s.push_token(:BYTE_UNIT)
60
+ when s.scan(/k/) then s.push_token(:UNIT)
61
+ when s.scan(/\d+\.\d+/) then s.push_token(:FLOAT, s.matched.to_f)
62
+ when s.scan(/\d+/) then s.push_token(:INTEGER, s.matched.to_i)
63
+ when s.scan(/F\b/) then s.push_token(:FAILED)
64
+ when s.scan(/\w+/) then s.push_token(:IDENTIFIER)
65
+ else
66
+ s.unexpected_token
67
+ end
68
+ end
69
+
70
+ @tokens = s.tokens
71
+
72
+ do_parse
73
+ end
74
+
75
+ def next_token
76
+ @tokens.shift
77
+ end
78
+
79
+ def on_error(error_token_id, error_value, value_stack)
80
+ raise(Racc::ParseError, "parse error on value \"#{error_value[:value]}\" (#{token_to_str(error_token_id)}) on line #{error_value[:lineno]}:\n#{error_value[:line]}\n#{' ' * error_value[:pos]}^#{'~' * (error_value[:value].to_s.length - 1)}")
81
+ end
82
+ ...end mdstat_parser.y/module_eval...
83
+ ##### State transition tables begin ###
84
+
85
+ racc_action_table = [
86
+ 10, 13, 14, 60, 10, 29, 3, 4, 6, 7,
87
+ 15, 16, 17, 18, 19, 11, 61, 62, 63, 20,
88
+ 21, 22, 23, 24, 10, 27, 28, 31, 32, 33,
89
+ 35, 37, 38, 39, 40, 41, 42, 43, 44, 45,
90
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 56,
91
+ 58, 64, 65, 66, 67, 68, 69, 70, 71, 72,
92
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
93
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92 ]
94
+
95
+ racc_action_check = [
96
+ 5, 10, 10, 56, 25, 25, 0, 1, 3, 4,
97
+ 11, 12, 13, 14, 15, 5, 56, 56, 56, 16,
98
+ 17, 18, 19, 20, 21, 22, 23, 27, 29, 31,
99
+ 32, 34, 35, 36, 37, 39, 40, 41, 42, 43,
100
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
101
+ 55, 58, 59, 64, 65, 66, 67, 68, 69, 70,
102
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
103
+ 81, 82, 83, 84, 85, 86, 87, 89, 90, 91 ]
104
+
105
+ racc_action_pointer = [
106
+ -10, 7, nil, -19, 9, -11, nil, nil, nil, nil,
107
+ -26, -17, -17, 1, 1, -22, 2, 3, -8, 11,
108
+ -6, 13, -6, -11, nil, -7, nil, 19, nil, 24,
109
+ nil, -3, 6, nil, 18, 22, 5, 22, nil, 23,
110
+ 3, 7, 26, 27, 15, 12, 35, 15, 11, 34,
111
+ 44, 18, 36, 31, nil, 47, -3, nil, 24, 18,
112
+ nil, nil, nil, nil, 41, 44, 25, 21, 45, 27,
113
+ 44, 48, 33, 32, 51, 52, 60, 34, 38, 59,
114
+ 36, 36, 59, 62, 68, 60, 68, 54, nil, 43,
115
+ 66, 56, nil ]
116
+
117
+ racc_action_default = [
118
+ -25, -25, -6, -25, -25, -25, -4, 93, -1, -5,
119
+ -25, -25, -2, -25, -25, -25, -25, -25, -25, -25,
120
+ -25, -25, -11, -25, -3, -25, -9, -25, -24, -25,
121
+ -8, -25, -13, -10, -15, -25, -25, -25, -12, -25,
122
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
123
+ -25, -25, -25, -19, -14, -17, -25, -7, -25, -25,
124
+ -20, -21, -22, -23, -25, -25, -25, -25, -25, -25,
125
+ -25, -25, -25, -25, -25, -25, -25, -25, -25, -25,
126
+ -25, -25, -25, -25, -25, -25, -25, -25, -16, -25,
127
+ -25, -25, -18 ]
128
+
129
+ racc_goto_table = [
130
+ 9, 1, 2, 5, 8, 12, 25, 34, 36, 55,
131
+ 57, 59, nil, nil, nil, nil, 26, nil, nil, nil,
132
+ 30 ]
133
+
134
+ racc_goto_check = [
135
+ 6, 1, 2, 3, 4, 5, 7, 8, 9, 10,
136
+ 11, 12, nil, nil, nil, nil, 6, nil, nil, nil,
137
+ 6 ]
138
+
139
+ racc_goto_pointer = [
140
+ nil, 1, 2, 1, -1, -1, -5, -15, -25, -26,
141
+ -44, -45, -45 ]
142
+
143
+ racc_goto_default = [
144
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
145
+ nil, nil, nil ]
146
+
147
+ racc_reduce_table = [
148
+ 0, 0, :racc_error,
149
+ 3, 39, :_reduce_1,
150
+ 3, 40, :_reduce_none,
151
+ 4, 43, :_reduce_none,
152
+ 0, 43, :_reduce_none,
153
+ 2, 41, :_reduce_5,
154
+ 0, 41, :_reduce_6,
155
+ 19, 44, :_reduce_7,
156
+ 2, 45, :_reduce_none,
157
+ 1, 45, :_reduce_none,
158
+ 7, 44, :_reduce_none,
159
+ 4, 44, :_reduce_none,
160
+ 2, 46, :_reduce_none,
161
+ 0, 46, :_reduce_none,
162
+ 9, 47, :_reduce_none,
163
+ 0, 47, :_reduce_none,
164
+ 14, 49, :_reduce_none,
165
+ 0, 49, :_reduce_none,
166
+ 18, 48, :_reduce_none,
167
+ 0, 48, :_reduce_none,
168
+ 1, 50, :_reduce_none,
169
+ 1, 50, :_reduce_none,
170
+ 1, 50, :_reduce_none,
171
+ 1, 50, :_reduce_none,
172
+ 5, 42, :_reduce_none ]
173
+
174
+ racc_reduce_n = 25
175
+
176
+ racc_shift_n = 93
177
+
178
+ racc_token_table = {
179
+ false => 0,
180
+ :error => 1,
181
+ :ALGORITHM => 2,
182
+ :BITMAP => 3,
183
+ :BLOCKS => 4,
184
+ :BYTE_UNIT => 5,
185
+ :CHECK => 6,
186
+ :CHUNK => 7,
187
+ :FAILED => 8,
188
+ :FINISH => 9,
189
+ :FLOAT => 10,
190
+ :IDENTIFIER => 11,
191
+ :INTEGER => 12,
192
+ :LEVEL => 13,
193
+ :MIN => 14,
194
+ :PAGES => 15,
195
+ :PERSONALITIES => 16,
196
+ :PERSONALITY => 17,
197
+ :PROGRESS => 18,
198
+ :RECOVERY => 19,
199
+ :RESHAPE => 20,
200
+ :RESYNC => 21,
201
+ :SPEED => 22,
202
+ :SPEED_UNIT => 23,
203
+ :SUPER => 24,
204
+ :UNIT => 25,
205
+ :UNUSED_DEVICES => 26,
206
+ ":" => 27,
207
+ "[" => 28,
208
+ "]" => 29,
209
+ "/" => 30,
210
+ "(" => 31,
211
+ ")" => 32,
212
+ "," => 33,
213
+ "=" => 34,
214
+ "%" => 35,
215
+ "<" => 36,
216
+ ">" => 37 }
217
+
218
+ racc_nt_base = 38
219
+
220
+ racc_use_result_var = true
221
+
222
+ Racc_arg = [
223
+ racc_action_table,
224
+ racc_action_check,
225
+ racc_action_default,
226
+ racc_action_pointer,
227
+ racc_goto_table,
228
+ racc_goto_check,
229
+ racc_goto_default,
230
+ racc_goto_pointer,
231
+ racc_nt_base,
232
+ racc_reduce_table,
233
+ racc_token_table,
234
+ racc_shift_n,
235
+ racc_reduce_n,
236
+ racc_use_result_var ]
237
+
238
+ Racc_token_to_s_table = [
239
+ "$end",
240
+ "error",
241
+ "ALGORITHM",
242
+ "BITMAP",
243
+ "BLOCKS",
244
+ "BYTE_UNIT",
245
+ "CHECK",
246
+ "CHUNK",
247
+ "FAILED",
248
+ "FINISH",
249
+ "FLOAT",
250
+ "IDENTIFIER",
251
+ "INTEGER",
252
+ "LEVEL",
253
+ "MIN",
254
+ "PAGES",
255
+ "PERSONALITIES",
256
+ "PERSONALITY",
257
+ "PROGRESS",
258
+ "RECOVERY",
259
+ "RESHAPE",
260
+ "RESYNC",
261
+ "SPEED",
262
+ "SPEED_UNIT",
263
+ "SUPER",
264
+ "UNIT",
265
+ "UNUSED_DEVICES",
266
+ "\":\"",
267
+ "\"[\"",
268
+ "\"]\"",
269
+ "\"/\"",
270
+ "\"(\"",
271
+ "\")\"",
272
+ "\",\"",
273
+ "\"=\"",
274
+ "\"%\"",
275
+ "\"<\"",
276
+ "\">\"",
277
+ "$start",
278
+ "target",
279
+ "personalities",
280
+ "devices",
281
+ "unused_devices",
282
+ "list_of_personalities",
283
+ "device",
284
+ "list_of_devices",
285
+ "super",
286
+ "level",
287
+ "progress",
288
+ "bitmap",
289
+ "progress_action" ]
290
+
291
+ Racc_debug_parser = false
292
+
293
+ ##### State transition tables end #####
294
+
295
+ # reduce 0 omitted
296
+
297
+ module_eval(<<'.,.,', 'mdstat_parser.y', 3)
298
+ def _reduce_1(val, _values, result)
299
+ result = val[1]
300
+ result
301
+ end
302
+ .,.,
303
+
304
+ # reduce 2 omitted
305
+
306
+ # reduce 3 omitted
307
+
308
+ # reduce 4 omitted
309
+
310
+ module_eval(<<'.,.,', 'mdstat_parser.y', 10)
311
+ def _reduce_5(val, _values, result)
312
+ result = val[0].merge(val[1])
313
+ result
314
+ end
315
+ .,.,
316
+
317
+ module_eval(<<'.,.,', 'mdstat_parser.y', 11)
318
+ def _reduce_6(val, _values, result)
319
+ result = {}
320
+ result
321
+ end
322
+ .,.,
323
+
324
+ module_eval(<<'.,.,', 'mdstat_parser.y', 13)
325
+ def _reduce_7(val, _values, result)
326
+ result = { val[0][:value] => val[15][:value] }
327
+ result
328
+ end
329
+ .,.,
330
+
331
+ # reduce 8 omitted
332
+
333
+ # reduce 9 omitted
334
+
335
+ # reduce 10 omitted
336
+
337
+ # reduce 11 omitted
338
+
339
+ # reduce 12 omitted
340
+
341
+ # reduce 13 omitted
342
+
343
+ # reduce 14 omitted
344
+
345
+ # reduce 15 omitted
346
+
347
+ # reduce 16 omitted
348
+
349
+ # reduce 17 omitted
350
+
351
+ # reduce 18 omitted
352
+
353
+ # reduce 19 omitted
354
+
355
+ # reduce 20 omitted
356
+
357
+ # reduce 21 omitted
358
+
359
+ # reduce 22 omitted
360
+
361
+ # reduce 23 omitted
362
+
363
+ # reduce 24 omitted
364
+
365
+ def _reduce_none(val, _values, result)
366
+ val[0]
367
+ end
368
+
369
+ end # class MdstatParser
370
+ end # module Tools
371
+ end # module Riemann
@@ -9,45 +9,52 @@ require 'racc/parser.rb'
9
9
 
10
10
  require 'strscan'
11
11
 
12
+ require 'riemann/tools/utils'
13
+
12
14
  module Riemann
13
15
  module Tools
14
16
  class UptimeParser < Racc::Parser
15
17
 
16
- module_eval(<<'...end uptime_parser.y/module_eval...', 'uptime_parser.y', 43)
18
+ module_eval(<<'...end uptime_parser.y/module_eval...', 'uptime_parser.y', 45)
17
19
 
18
20
  def parse(text)
19
- s = StringScanner.new(text)
20
- @tokens = []
21
+ s = Utils::StringTokenizer.new(text)
21
22
 
22
23
  until s.eos? do
23
24
  case
24
- when s.scan(/\n/) then # ignore
25
- when s.scan(/\s+/) then # ignore
26
-
27
- when s.scan(/:/) then @tokens << [':', s.matched]
28
- when s.scan(/,/) then @tokens << [',', s.matched]
29
- when s.scan(/\d+[,.]\d+/) then @tokens << [:FLOAT, s.matched.sub(',', '.').to_f]
30
- when s.scan(/\d+/) then @tokens << [:INTEGER, s.matched.to_i]
31
- when s.scan(/AM/) then @tokens << [:AM, s.matched]
32
- when s.scan(/PM/) then @tokens << [:PM, s.matched]
33
- when s.scan(/up/) then @tokens << [:UP, s.matched]
34
- when s.scan(/days?/) then @tokens << [:DAYS, s.matched]
35
- when s.scan(/hrs?/) then @tokens << [:HRS, s.matched]
36
- when s.scan(/mins?/) then @tokens << [:MINS, s.matched]
37
- when s.scan(/secs?/) then @tokens << [:SECS, s.matched]
38
- when s.scan(/users?/) then @tokens << [:USERS, s.matched]
39
- when s.scan(/load averages?:/) then @tokens << [:LOAD_AVERAGES, s.matched]
25
+ when s.scan(/\n/) then s.push_token(nil)
26
+ when s.scan(/\s+/) then s.push_token(nil)
27
+
28
+ when s.scan(/:/) then s.push_token(':')
29
+ when s.scan(/,/) then s.push_token(',')
30
+ when s.scan(/\d+[,.]\d+/) then s.push_token(:FLOAT, s.matched.sub(',', '.').to_f)
31
+ when s.scan(/\d+/) then s.push_token(:INTEGER, s.matched.to_i)
32
+ when s.scan(/AM/) then s.push_token(:AM)
33
+ when s.scan(/PM/) then s.push_token(:PM)
34
+ when s.scan(/up/) then s.push_token(:UP)
35
+ when s.scan(/days?/) then s.push_token(:DAYS)
36
+ when s.scan(/hrs?/) then s.push_token(:HRS)
37
+ when s.scan(/mins?/) then s.push_token(:MINS)
38
+ when s.scan(/secs?/) then s.push_token(:SECS)
39
+ when s.scan(/users?/) then s.push_token(:USERS)
40
+ when s.scan(/load averages?:/) then s.push_token(:LOAD_AVERAGES)
40
41
  else
41
- raise s.rest
42
+ raise s.unexpected_token
42
43
  end
43
44
  end
44
45
 
46
+ @tokens = s.tokens
47
+
45
48
  do_parse
46
49
  end
47
50
 
48
51
  def next_token
49
52
  @tokens.shift
50
53
  end
54
+
55
+ def on_error(error_token_id, error_value, value_stack)
56
+ raise(Racc::ParseError, "parse error on value \"#{error_value[:value]}\" (#{token_to_str(error_token_id)}) on line #{error_value[:lineno]}:\n#{error_value[:line]}\n#{' ' * error_value[:pos]}^#{'~' * (error_value[:value].to_s.length - 1)}")
57
+ end
51
58
  ...end uptime_parser.y/module_eval...
52
59
  ##### State transition tables begin ###
53
60
 
@@ -113,7 +120,7 @@ racc_reduce_table = [
113
120
  2, 23, :_reduce_16,
114
121
  2, 24, :_reduce_17,
115
122
  2, 25, :_reduce_18,
116
- 2, 19, :_reduce_none,
123
+ 2, 19, :_reduce_19,
117
124
  4, 20, :_reduce_20,
118
125
  6, 20, :_reduce_21 ]
119
126
 
@@ -265,51 +272,56 @@ module_eval(<<'.,.,', 'uptime_parser.y', 18)
265
272
 
266
273
  module_eval(<<'.,.,', 'uptime_parser.y', 20)
267
274
  def _reduce_14(val, _values, result)
268
- result = val[0] * 86400
275
+ result = val[0][:value] * 86400
269
276
  result
270
277
  end
271
278
  .,.,
272
279
 
273
280
  module_eval(<<'.,.,', 'uptime_parser.y', 22)
274
281
  def _reduce_15(val, _values, result)
275
- result = val[0] * 3600 + val[2] * 60
282
+ result = val[0][:value] * 3600 + val[2][:value] * 60
276
283
  result
277
284
  end
278
285
  .,.,
279
286
 
280
287
  module_eval(<<'.,.,', 'uptime_parser.y', 24)
281
288
  def _reduce_16(val, _values, result)
282
- result = val[0] * 3600
289
+ result = val[0][:value] * 3600
283
290
  result
284
291
  end
285
292
  .,.,
286
293
 
287
294
  module_eval(<<'.,.,', 'uptime_parser.y', 26)
288
295
  def _reduce_17(val, _values, result)
289
- result = val[0] * 60
296
+ result = val[0][:value] * 60
290
297
  result
291
298
  end
292
299
  .,.,
293
300
 
294
301
  module_eval(<<'.,.,', 'uptime_parser.y', 28)
295
302
  def _reduce_18(val, _values, result)
296
- result = val[0]
303
+ result = val[0][:value]
297
304
  result
298
305
  end
299
306
  .,.,
300
307
 
301
- # reduce 19 omitted
308
+ module_eval(<<'.,.,', 'uptime_parser.y', 30)
309
+ def _reduce_19(val, _values, result)
310
+ result = val[0][:value]
311
+ result
312
+ end
313
+ .,.,
302
314
 
303
315
  module_eval(<<'.,.,', 'uptime_parser.y', 32)
304
316
  def _reduce_20(val, _values, result)
305
- result = { 1 => val[1], 5 => val[2], 15 => val[3] }
317
+ result = { 1 => val[1][:value], 5 => val[2][:value], 15 => val[3][:value] }
306
318
  result
307
319
  end
308
320
  .,.,
309
321
 
310
322
  module_eval(<<'.,.,', 'uptime_parser.y', 33)
311
323
  def _reduce_21(val, _values, result)
312
- result = { 1 => val[1], 5 => val[3], 15 => val[5] }
324
+ result = { 1 => val[1][:value], 5 => val[3][:value], 15 => val[5][:value] }
313
325
  result
314
326
  end
315
327
  .,.,
@@ -3,6 +3,54 @@
3
3
  module Riemann
4
4
  module Tools
5
5
  module Utils # :nodoc:
6
+ class StringTokenizer
7
+ attr_reader :tokens
8
+
9
+ def initialize(text)
10
+ @scanner = StringScanner.new(text)
11
+
12
+ @lineno = 1
13
+ @pos = 0
14
+ @line = next_line
15
+ @tokens = []
16
+ end
17
+
18
+ def scan(expression)
19
+ @scanner.scan(expression)
20
+ end
21
+
22
+ def eos?
23
+ @scanner.eos?
24
+ end
25
+
26
+ def matched
27
+ @scanner.matched
28
+ end
29
+
30
+ def next_line
31
+ (@scanner.check_until(/\n/) || @scanner.rest).chomp
32
+ end
33
+
34
+ def push_token(token, value = nil)
35
+ value ||= @scanner.matched
36
+
37
+ if value == "\n"
38
+ @lineno += 1
39
+ @line = next_line
40
+ @pos = pos = 0
41
+ else
42
+ pos = @pos
43
+ @pos += @scanner.matched.length
44
+ end
45
+
46
+ @tokens << [token, { value: value, line: @line, lineno: @lineno, pos: pos }] if token
47
+ end
48
+
49
+ def unexpected_token
50
+ raise(Racc::ParseError, "unexpected data on line #{@lineno}:\n#{@line}\n#{' ' * @pos}^")
51
+ end
52
+ end
53
+
6
54
  def reverse_numeric_sort_with_header(data, header: 1, count: 10)
7
55
  lines = data.chomp.split("\n")
8
56
  header = lines.shift(header)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Riemann
4
4
  module Tools # :nodoc:
5
- VERSION = '1.2.0'
5
+ VERSION = '1.5.0'
6
6
  end
7
7
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ require 'riemann/tools'
6
+
7
+ module Riemann
8
+ module Tools
9
+ class Zpool
10
+ include Riemann::Tools
11
+
12
+ def tick
13
+ output, status = Open3.capture2e('zpool status -x')
14
+
15
+ state = if status.success?
16
+ case output
17
+ when "all pools are healthy\n" then 'ok'
18
+ when /state: (DEGRADED|FAULTED)/ then 'critical'
19
+ else
20
+ 'warning'
21
+ end
22
+ else
23
+ 'critical'
24
+ end
25
+
26
+ report(
27
+ service: 'zpool health',
28
+ description: output,
29
+ state: state,
30
+ )
31
+ rescue Errno::ENOENT => e
32
+ report(
33
+ service: 'zpool health',
34
+ description: e.message,
35
+ state: 'critical',
36
+ )
37
+ end
38
+ end
39
+ end
40
+ end
@@ -24,8 +24,14 @@ Gem::Specification.new do |spec|
24
24
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
25
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
26
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } -
27
- ['lib/riemann/tools/uptime_parser.y'] +
28
- ['lib/riemann/tools/uptime_parser.tab.rb']
27
+ [
28
+ 'lib/riemann/tools/mdstat_parser.y',
29
+ 'lib/riemann/tools/uptime_parser.y',
30
+ ] +
31
+ [
32
+ 'lib/riemann/tools/mdstat_parser.tab.rb',
33
+ 'lib/riemann/tools/uptime_parser.tab.rb',
34
+ ]
29
35
  end
30
36
  spec.bindir = 'bin'
31
37
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
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.2.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Kingsbury
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-17 00:00:00.000000000 Z
11
+ date: 2022-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -172,6 +172,7 @@ executables:
172
172
  - riemann-haproxy
173
173
  - riemann-health
174
174
  - riemann-kvminstance
175
+ - riemann-md
175
176
  - riemann-memcached
176
177
  - riemann-net
177
178
  - riemann-nginx-status
@@ -181,6 +182,7 @@ executables:
181
182
  - riemann-varnish
182
183
  - riemann-wrapper
183
184
  - riemann-zookeeper
185
+ - riemann-zpool
184
186
  extensions: []
185
187
  extra_rdoc_files: []
186
188
  files:
@@ -212,6 +214,7 @@ files:
212
214
  - bin/riemann-haproxy
213
215
  - bin/riemann-health
214
216
  - bin/riemann-kvminstance
217
+ - bin/riemann-md
215
218
  - bin/riemann-memcached
216
219
  - bin/riemann-net
217
220
  - bin/riemann-nginx-status
@@ -221,6 +224,7 @@ files:
221
224
  - bin/riemann-varnish
222
225
  - bin/riemann-wrapper
223
226
  - bin/riemann-zookeeper
227
+ - bin/riemann-zpool
224
228
  - lib/riemann/tools.rb
225
229
  - lib/riemann/tools/apache_status.rb
226
230
  - lib/riemann/tools/bench.rb
@@ -234,6 +238,8 @@ files:
234
238
  - lib/riemann/tools/haproxy.rb
235
239
  - lib/riemann/tools/health.rb
236
240
  - lib/riemann/tools/kvm.rb
241
+ - lib/riemann/tools/md.rb
242
+ - lib/riemann/tools/mdstat_parser.tab.rb
237
243
  - lib/riemann/tools/memcached.rb
238
244
  - lib/riemann/tools/net.rb
239
245
  - lib/riemann/tools/nginx_status.rb
@@ -246,6 +252,7 @@ files:
246
252
  - lib/riemann/tools/varnish.rb
247
253
  - lib/riemann/tools/version.rb
248
254
  - lib/riemann/tools/zookeeper.rb
255
+ - lib/riemann/tools/zpool.rb
249
256
  - riemann-tools.gemspec
250
257
  - tools/riemann-aws/LICENSE
251
258
  - tools/riemann-aws/README.md