riemann-babbler 1.1.0pre2 → 1.1.6

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.
Files changed (37) hide show
  1. data/.gitignore +0 -1
  2. data/Gemfile +2 -1
  3. data/Gemfile.lock +6 -2
  4. data/README.md +0 -8
  5. data/Rakefile +0 -13
  6. data/bin/riemann-babbler +4 -3
  7. data/config.yml +3 -1
  8. data/lib/riemann/{babbler/plugin.rb → babbler.rb} +14 -10
  9. data/lib/riemann/babbler/plugins/cpu.rb +5 -1
  10. data/lib/riemann/babbler/plugins/{cpufan.rb → cpu_fan.rb} +2 -2
  11. data/lib/riemann/babbler/plugins/{cputemp.rb → cpu_temp.rb} +2 -2
  12. data/lib/riemann/babbler/plugins/disk.rb +13 -7
  13. data/lib/riemann/babbler/plugins/exim4.rb +1 -1
  14. data/lib/riemann/babbler/plugins/find_files.rb +27 -0
  15. data/lib/riemann/babbler/plugins/http.rb +2 -2
  16. data/lib/riemann/babbler/plugins/la.rb +1 -1
  17. data/lib/riemann/babbler/plugins/mdadm.rb +18 -4
  18. data/lib/riemann/babbler/plugins/{megacli.rb → mega_cli.rb} +1 -1
  19. data/lib/riemann/babbler/plugins/memory.rb +22 -8
  20. data/lib/riemann/babbler/plugins/net.rb +23 -3
  21. data/lib/riemann/babbler/plugins/net_stat.rb +33 -0
  22. data/lib/riemann/babbler/plugins/nginx.rb +3 -12
  23. data/lib/riemann/babbler/plugins/runit.rb +5 -3
  24. data/lib/riemann/babbler/plugins/status_file.rb +23 -0
  25. data/lib/riemann/babbler/plugins/tw_cli.rb +22 -0
  26. data/lib/{start.rb → riemann/babbler/start.rb} +5 -4
  27. data/lib/riemann/babbler/support/monkey_patches.rb +3 -3
  28. data/lib/riemann/babbler/support/plugin_helpers.rb +21 -1
  29. data/lib/riemann/{version.rb → babbler/version.rb} +1 -1
  30. data/riemann-babbler.gemspec +6 -7
  31. data/spec/default.rb +2 -3
  32. metadata +52 -21
  33. data/ext/sysinfo/extconf.rb +0 -3
  34. data/ext/sysinfo/sysinfo.c +0 -476
  35. data/ext/sysinfo/sysinfo.h +0 -2
  36. data/lib/riemann/babbler/plugins/netstat.rb +0 -15
  37. data/lib/riemann/babbler/sysinfo.rb +0 -1
data/.gitignore CHANGED
@@ -2,4 +2,3 @@ pkg/
2
2
  .idea
3
3
  .rvmrc
4
4
  *.swp
5
- Makefile
data/Gemfile CHANGED
@@ -6,8 +6,9 @@ gem 'logger'
6
6
  gem 'trollop'
7
7
  gem 'sys-filesystem'
8
8
  gem 'rest-client'
9
- gem 'sequel'
10
9
  gem 'net-ping'
10
+ gem 'file-tail'
11
+ gem 'sys-proctable'
11
12
 
12
13
  gem 'rspec'
13
14
  gem 'rake'
data/Gemfile.lock CHANGED
@@ -8,6 +8,8 @@ GEM
8
8
  yamler (>= 0.1.0)
9
9
  diff-lcs (1.2.2)
10
10
  ffi (1.4.0)
11
+ file-tail (1.0.12)
12
+ tins (~> 0.5)
11
13
  logger (1.2.8)
12
14
  method_source (0.8.1)
13
15
  mime-types (1.21)
@@ -33,10 +35,11 @@ GEM
33
35
  rspec-expectations (2.13.0)
34
36
  diff-lcs (>= 1.1.3, < 2.0)
35
37
  rspec-mocks (2.13.0)
36
- sequel (3.46.0)
37
38
  slop (3.4.3)
38
39
  sys-filesystem (1.1.0)
39
40
  ffi
41
+ sys-proctable (0.9.3)
42
+ tins (0.8.0)
40
43
  trollop (2.0)
41
44
  yamler (0.1.0)
42
45
 
@@ -46,6 +49,7 @@ PLATFORMS
46
49
  DEPENDENCIES
47
50
  awesome_print
48
51
  configatron
52
+ file-tail
49
53
  logger
50
54
  net-ping
51
55
  pry
@@ -53,6 +57,6 @@ DEPENDENCIES
53
57
  rest-client
54
58
  riemann-client
55
59
  rspec
56
- sequel
57
60
  sys-filesystem
61
+ sys-proctable
58
62
  trollop
data/README.md CHANGED
@@ -1,13 +1,5 @@
1
1
  [![Build Status](https://travis-ci.org/vadv/riemann-babbler.png)](https://travis-ci.org/vadv/riemann-babbler)
2
2
 
3
- ### Beware!
4
- Currently I'm working on c-ext from zabbix.
5
- It's not all fully working :)
6
- Use stable gem please!
7
- ```
8
- gem "riemann-babbler", "~> 1.0.7.3"
9
- ```
10
-
11
3
  ### Install
12
4
  ```
13
5
  gem install riemann-babbler
data/Rakefile CHANGED
@@ -1,14 +1 @@
1
- require 'rspec/core/rake_task'
2
1
  require 'bundler/gem_tasks'
3
-
4
- RSpec::Core::RakeTask.new('spec')
5
- task :build do
6
- Dir.chdir('ext/sysinfo') do
7
- output = `ruby extconf.rb`
8
- raise output unless $? == 0
9
- output = `make`
10
- raise output unless $? == 0
11
- end
12
- end
13
-
14
- task :spec => :build
data/bin/riemann-babbler CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
- #encoding: utf-8
2
+ # coding: utf-8
3
3
 
4
4
  require 'trollop'
5
5
  require 'configatron'
6
6
 
7
- require File.expand_path('../../lib/riemann/version', __FILE__)
8
- require File.expand_path('../../lib/start', __FILE__)
7
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ require 'riemann/babbler/version'
9
+ require 'riemann/babbler/start'
9
10
 
10
11
  opts = Trollop::options do
11
12
  version "Riemann babbler #{Riemann::Babbler::VERSION}"
data/config.yml CHANGED
@@ -40,7 +40,6 @@ plugins:
40
40
 
41
41
  net:
42
42
  service: net
43
- interval: 60
44
43
 
45
44
  cpufan:
46
45
  service: cpufan
@@ -57,6 +56,9 @@ plugins:
57
56
  megacli:
58
57
  service: megacli
59
58
 
59
+ twcli:
60
+ interval: 300
61
+
60
62
  nginx:
61
63
  service: nginx
62
64
 
@@ -1,15 +1,14 @@
1
- #encoding: utf-8
1
+ # encoding: utf-8
2
2
 
3
- require File.expand_path('../support/plugin_helpers', __FILE__)
3
+ require 'riemann/babbler/support/plugin_helpers'
4
4
  require 'riemann/client'
5
5
  require 'open3'
6
6
  require 'timeout'
7
7
  require 'rest_client'
8
8
  require 'socket'
9
9
  require 'net/ping'
10
- require 'sequel'
11
- require 'riemann/babbler/sysinfo'
12
- require File.expand_path('../support/monkey_patches', __FILE__)
10
+ require 'file/tail'
11
+ require 'riemann/babbler/support/monkey_patches'
13
12
 
14
13
 
15
14
  # Базовое описание плагина
@@ -66,9 +65,9 @@ module Riemann
66
65
  def report_with_diff(event)
67
66
  current_metric = event[:metric]
68
67
  if @storage.has_key?(event[:service])
69
- next if @storage[ event[:service] ].nil?
70
- next if current_metric + @storage[ event[:service] ] > 2**64
71
- event[:metric] = current_metric - @storage[ event[:service] ]
68
+ unless current_metric + @storage[event[:service]] > 2**64
69
+ event[:metric] = current_metric - @storage[event[:service]]
70
+ end unless @storage[event[:service]].nil?
72
71
  end
73
72
  @storage[ event[:service] ] = current_metric
74
73
  event.delete(:as_diff)
@@ -101,7 +100,7 @@ module Riemann
101
100
  if plugin.run.nil?
102
101
  true
103
102
  else
104
- plugin.run == true ? true : false
103
+ plugin.run ? true : false
105
104
  end
106
105
  end
107
106
 
@@ -122,7 +121,10 @@ module Riemann
122
121
  t0 = Time.now
123
122
  loop do
124
123
  begin
125
- tick
124
+ Timeout::timeout( plugin.interval ) { tick }
125
+ rescue TimeoutError
126
+ report({:state => 'critical', :service => plugin.service, :description => 'Broken plugin: deadlock'})
127
+ logger.error "Plugin #{self.class.name} timed out!"
126
128
  rescue => e
127
129
  logger.error "Plugin #{self.class.name} : #{e.class} #{e}\n#{e.backtrace.join "\n"}"
128
130
  end
@@ -136,6 +138,8 @@ module Riemann
136
138
  return 'critical' if my_state.nil?
137
139
  if plugin.states.warning.nil?
138
140
  my_state >= plugin.states.critical ? 'critical' : 'ok'
141
+ elsif plugin.states.critical.nil?
142
+ my_state >= plugin.states.warning ? 'warning' : 'ok'
139
143
  else
140
144
  case
141
145
  when my_state.between?(plugin.states.warning, plugin.states.critical)
@@ -2,13 +2,17 @@
2
2
 
3
3
  class Riemann::Babbler::Cpu < Riemann::Babbler
4
4
 
5
+ def desc
6
+ "#{shell('ps -eo pcpu,pid,cmd --sort -pcpu | head -3').chomp}"
7
+ end
8
+
5
9
  def init
6
10
  @old_cpu = Hash.new
7
11
  end
8
12
 
9
13
  def collect
10
14
  array = Array.new
11
- description = 'Cpu usage'
15
+ description = desc
12
16
  File.read('/proc/stat').split("\n").each do |cpu_line|
13
17
 
14
18
  # проверяем есть строчка /cpu\d+/ или /cpu / и сграбливаем это в переменную
@@ -1,4 +1,4 @@
1
- class Riemann::Babbler::Cpufan < Riemann::Babbler
1
+ class Riemann::Babbler::CpuFan < Riemann::Babbler
2
2
 
3
3
  def init
4
4
  plugin.set_default(:service, 'cpufan')
@@ -13,7 +13,7 @@ class Riemann::Babbler::Cpufan < Riemann::Babbler
13
13
  end
14
14
 
15
15
  def collect
16
- { :service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => "CPU Fan Speed" }
16
+ { :service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => 'CPU Fan Speed'}
17
17
  end
18
18
 
19
19
  end
@@ -1,4 +1,4 @@
1
- class Riemann::Babbler::Cputemp < Riemann::Babbler
1
+ class Riemann::Babbler::CpuTemp < Riemann::Babbler
2
2
 
3
3
  def init
4
4
  plugin.set_default(:service, 'cputemp')
@@ -13,7 +13,7 @@ class Riemann::Babbler::Cputemp < Riemann::Babbler
13
13
  end
14
14
 
15
15
  def collect
16
- { :service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => "CPU Temperature" }
16
+ { :service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => 'CPU Temperature'}
17
17
  end
18
18
 
19
19
  end
@@ -2,6 +2,9 @@
2
2
 
3
3
  class Riemann::Babbler::Disk < Riemann::Babbler
4
4
 
5
+ require 'sys/filesystem'
6
+ include Sys
7
+
5
8
  NOT_MONITORING_FS = %w(sysfs nfs devpts squashfs proc devtmpfs)
6
9
 
7
10
  def collect
@@ -9,18 +12,21 @@ class Riemann::Babbler::Disk < Riemann::Babbler
9
12
  # точнее выбираем из mounts только те, у которых fstype не попадает
10
13
  # в NOT_MONITORING_FS
11
14
  monit_points = []
12
- File.read('/proc/mounts').split("\n").each do |line|
13
- mtab = line.split(/\s+/)
14
- monit_points << mtab[1] unless NOT_MONITORING_FS.include? mtab[2]
15
+ File.open('/proc/mounts', 'r') do |file|
16
+ while (line = file.gets)
17
+ mtab = line.split(/\s+/)
18
+ monit_points << mtab[1] unless NOT_MONITORING_FS.include? mtab[2]
19
+ end
15
20
  end
16
21
  disk = Array.new
17
22
  monit_points.each do |point|
23
+ point_stat = Filesystem.stat point
18
24
  human_point = point == '/' ? '/root' : point
19
25
  human_point = human_point.gsub(/^\//, '').gsub(/\//, '_')
20
- disk << { :service => plugin.service + " #{human_point} % block", :description => "Disk usage #{point}, %", :metric => SysInfo::FS::Block.pused(point) }
21
- disk << { :service => plugin.service + " #{human_point} % inode", :description => "Disk usage #{point}, inodes %", :metric => SysInfo::FS::Inode.pused(point)}
22
- disk << { :service => plugin.service + " #{human_point} abs free", :description => "Disk free #{point}, B", :metric => SysInfo::FS::Block.total(point), :state => 'ok'}
23
- disk << { :service => plugin.service + " #{human_point} abs total", :description => "Disk space #{point}, B", :metric => SysInfo::FS::Inode.total(point), :state => 'ok'}
26
+ disk << { :service => plugin.service + " #{human_point} % block", :description => "Disk usage #{point}, %", :metric => (1- point_stat.blocks_available.to_f/point_stat.blocks).round(2) * 100 } unless point_stat.blocks == 0
27
+ disk << { :service => plugin.service + " #{human_point} % inode", :description => "Disk usage #{point}, inodes %", :metric => (1 - point_stat.files_available.to_f/point_stat.files).round(2) * 100 } unless point_stat.files == 0
28
+ disk << { :service => plugin.service + " #{human_point} abs free", :description => "Disk free #{point}, B", :metric => point_stat.blocks_free * point_stat.block_size, :state => 'ok'}
29
+ disk << { :service => plugin.service + " #{human_point} abs total", :description => "Disk space #{point}, B", :metric => point_stat.blocks * point_stat.block_size, :state => 'ok'}
24
30
  end
25
31
  disk
26
32
  end
@@ -13,7 +13,7 @@ class Riemann::Babbler::Exim4 < Riemann::Babbler
13
13
  end
14
14
 
15
15
  def collect
16
- { :service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => "Exim4: count frozen mails" }
16
+ { :service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => 'Exim4: count frozen mails'}
17
17
  end
18
18
 
19
19
  end
@@ -0,0 +1,27 @@
1
+ require 'find'
2
+
3
+ class Riemann::Babbler::Findfiles < Riemann::Babbler
4
+
5
+ def init
6
+ plugin.set_default(:service, 'find files')
7
+ plugin.set_default(:interval, 60)
8
+ plugin.set_default(:file_mask, '.*') # file search mask
9
+ plugin.set_default(:dir, '/tmp/directory') # search in dir
10
+ plugin.set_default(:age, 1440) # in minute
11
+ plugin.states.set_default(:warning, 5)
12
+ end
13
+
14
+ def collect
15
+ return [] unless File.directory?(plugin.dir)
16
+ files = 0
17
+ file_mask = Regexp.new(plugin.file_mask)
18
+ Find.find(plugin.dir).each do |file|
19
+ next unless File.file? file
20
+ next unless file_mask.match file
21
+ next unless Time.now.to_i - (plugin.age * 60) > File.new(file).mtime.to_i
22
+ files += 1
23
+ end
24
+ { :service => plugin.service, :metric => files, :description => "Count files in #{plugin.dir}"}
25
+ end
26
+
27
+ end
@@ -24,9 +24,9 @@ class Riemann::Babbler::Http < Riemann::Babbler
24
24
  command += " --max-time #{plugin.max_time} --fail"
25
25
  command += " #{plugin.url} -o /dev/null"
26
26
 
27
- out = shell(command)
27
+ out = shell(command).to_i
28
28
 
29
- if out.to_i != plugin.http_code
29
+ if out != plugin.http_code
30
30
  metric = 1
31
31
  else
32
32
  metric = 0
@@ -3,7 +3,7 @@
3
3
  class Riemann::Babbler::La < Riemann::Babbler
4
4
 
5
5
  def collect
6
- { :service => plugin.service + ' la_1', :description => 'LA averaged over 1 minute', :metric => File.read('/proc/loadavg').split(/\s+/)[2].to_f }
6
+ { :service => plugin.service + ' la_1', :description => 'LA averaged over 1 minute', :metric => File.read('/proc/loadavg').scan(/[\d\.]+/).first.to_f }
7
7
  end
8
8
 
9
9
  end
@@ -14,12 +14,26 @@ class Riemann::Babbler::Mdadm < Riemann::Babbler
14
14
  file = File.read('/proc/mdstat').split("\n")
15
15
  status = Array.new
16
16
  file.each_with_index do |line, index|
17
- next unless line.include? "_"
18
- device = file[index-1].split(":")[0].strip
19
- status << { :service => plugin.service + " #{device}", :metric => 1, :description => "mdadm failed device #{device}" }
17
+ next unless line.include? '_'
18
+ device = file[index-1].split(':')[0].strip
19
+ status << { :service => plugin.service + " #{device}", :metric => 1, :description => "mdadm failed device #{device}: #{get_failed_parts(device)}" }
20
20
  end
21
21
  status
22
22
  end
23
23
 
24
- end
24
+ def get_failed_parts (device)
25
+ begin
26
+ failed_parts = []
27
+ Dir["/sys/block/#{device}/md/dev-*"].each do |p|
28
+ state = File.read("#{p}/state").strip
29
+ next unless state != "in_sync"
30
+ p.gsub!(/.+\/dev-/,"")
31
+ failed_parts << "#{p} (#{state})"
32
+ end
33
+ failed_parts.join(", ")
34
+ rescue
35
+ nil
36
+ end
37
+ end
25
38
 
39
+ end
@@ -12,7 +12,7 @@ class Riemann::Babbler::MegaCli < Riemann::Babbler
12
12
  end
13
13
 
14
14
  def collect
15
- {:service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => "MegaCli status" }
15
+ {:service => plugin.service, :metric => shell(plugin.cmd).to_i, :description => 'MegaCli status'}
16
16
  end
17
17
 
18
18
  end
@@ -3,17 +3,31 @@
3
3
  class Riemann::Babbler::Memory < Riemann::Babbler
4
4
 
5
5
  def collect
6
- total = SysInfo::Memory.total
7
- free_bc = SysInfo::Memory.free + SysInfo::Memory.buffers + SysInfo::Memory.cached
6
+ m = File.read('/proc/meminfo').split(/\n/).inject({}) { |info, line|
7
+ x = line.split(/:?\s+/)
8
+ info[x[0]] = x[1].to_i
9
+ info
10
+ }
11
+ free = m['MemFree'].to_i * 1024
12
+ cached =m['Cached'].to_i * 1024
13
+ buffers =m['Buffers'].to_i * 1024
14
+ total = m['MemTotal'].to_i * 1024
15
+ used = total - free
16
+ free_bc = free + buffers + cached
17
+
8
18
  fraction = 1 - (free_bc.to_f / total)
19
+ swap_fraction = m['SwapTotal'] == 0 ? 0 : 1 - m['SwapFree'].to_f/m['SwapTotal']
20
+
21
+ desc = "#{shell('ps -eo pmem,pid,cmd --sort -pmem | head -3').chomp}"
9
22
  [
10
23
  { :service => plugin.service + ' % free', :description => 'Memory usage, %', :metric => fraction.round(2) * 100 },
11
- { :service => plugin.service + ' abs free', :description => "Memory free (Bytes)", :metric => SysInfo::Memory.free, :state => 'ok' },
12
- { :service => plugin.service + ' abs total', :description => "Memory total (Bytes)", :metric => total, :state => 'ok' },
13
- { :service => plugin.service + ' abs cached', :description => "Memory usage, cached (Bytes)", :metric => SysInfo::Memory.cached, :state => 'ok' },
14
- { :service => plugin.service + ' abs buffers', :description => "Memory usage, buffers (Bytes)", :metric => SysInfo::Memory.buffers, :state => 'ok' },
15
- { :service => plugin.service + ' abs used', :description => "Memory usage, used (Bytes)", :metric => SysInfo::Memory.total - SysInfo::Memory.free , :state => 'ok' },
16
- { :service => plugin.service + ' abs free_bc', :description => "Memory usage with cache и buffers (Bytes)", :metric => free_bc , :state => 'ok' }
24
+ { :service => plugin.service + ' % swap', :description => 'Swap usage, %', :metric => swap_fraction.round(2) * 100 },
25
+ { :service => plugin.service + ' abs free', :description => "Memory free (kB)\n\n #{desc}", :metric => free, :state => 'ok' },
26
+ { :service => plugin.service + ' abs total', :description => "Memory total (kB)\n\n #{desc}", :metric => total, :state => 'ok' },
27
+ { :service => plugin.service + ' abs cached', :description => "Memory usage, cached (kB)\n\n #{desc}", :metric => cached, :state => 'ok' },
28
+ { :service => plugin.service + ' abs buffers', :description => "Memory usage, buffers (kB)\n\n #{desc}", :metric => buffers, :state => 'ok' },
29
+ { :service => plugin.service + ' abs used', :description => "Memory usage, used (kB)\n\n #{desc}", :metric => used , :state => 'ok' },
30
+ { :service => plugin.service + ' abs free_bc', :description => "Memory usage with cache и buffers (kB)\n\n #{desc}", :metric => free_bc , :state => 'ok' }
17
31
  ]
18
32
  end
19
33
 
@@ -1,5 +1,21 @@
1
1
  class Riemann::Babbler::Net < Riemann::Babbler
2
2
 
3
+ WORDS = ['rx bytes',
4
+ 'rx packets',
5
+ 'rx errs',
6
+ 'rx drop',
7
+ 'rx fifo',
8
+ 'rx frame',
9
+ 'rx compressed',
10
+ 'rx multicast',
11
+ 'tx bytes',
12
+ 'tx packets',
13
+ 'tx drops',
14
+ 'tx fifo',
15
+ 'tx colls',
16
+ 'tx carrier',
17
+ 'tx compressed']
18
+
3
19
  def collect
4
20
  f = File.read('/proc/net/dev')
5
21
  status = Array.new
@@ -7,9 +23,13 @@ class Riemann::Babbler::Net < Riemann::Babbler
7
23
  iface = line.split(':')[0].strip
8
24
  iface.gsub!(/\./, '_')
9
25
  next unless line =~ /(\w*)\:\s*([\s\d]+)\s*/
10
- status << { :service => "#{plugin.service} #{iface} bytes out", :metric => SysInfo::Net.out(iface, 'bytes'), :as_diff => true }
11
- status << { :service => "#{plugin.service} #{iface} bytes in", :metric => SysInfo::Net.in(iface, 'bytes'), :as_diff => true }
12
- status << { :service => "#{plugin.service} #{iface} bytes errors", :metric => SysInfo::Net.total(iface, 'errors'), :state => 'ok' }
26
+ WORDS.map do |service|
27
+ "#{plugin.service} #{iface} #{service}"
28
+ end.zip(
29
+ $2.split(/\s+/).map { |str| str.to_i }
30
+ ).each do |service, value|
31
+ status << { :service => service, :metric => value, :as_diff => true}
32
+ end
13
33
  end
14
34
  status
15
35
  end