riemann-babbler 1.4.0 → 2.0.0pre1

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 (51) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +2 -16
  3. data/Gemfile.lock +25 -39
  4. data/LICENSE.txt +22 -0
  5. data/README.md +18 -16
  6. data/bin/riemann-babbler +30 -10
  7. data/lib/riemann/babbler/errors.rb +13 -0
  8. data/lib/riemann/babbler/logging.rb +36 -0
  9. data/lib/riemann/babbler/{support/deep_merge.rb → monkey_patches.rb} +25 -16
  10. data/lib/riemann/babbler/options.rb +43 -0
  11. data/lib/riemann/babbler/plugin.rb +154 -0
  12. data/lib/riemann/babbler/plugin_loader.rb +86 -0
  13. data/lib/riemann/babbler/plugins/cpu.rb +14 -11
  14. data/lib/riemann/babbler/plugins/cpu_fan.rb +2 -2
  15. data/lib/riemann/babbler/plugins/cpu_temp.rb +2 -2
  16. data/lib/riemann/babbler/plugins/disk.rb +12 -6
  17. data/lib/riemann/babbler/plugins/{diskstat.rb → disk_stat.rb} +18 -18
  18. data/lib/riemann/babbler/plugins/errors_reporter.rb +34 -0
  19. data/lib/riemann/babbler/plugins/exim4.rb +2 -2
  20. data/lib/riemann/babbler/plugins/find_files.rb +7 -7
  21. data/lib/riemann/babbler/plugins/haproxy.rb +7 -7
  22. data/lib/riemann/babbler/plugins/helpers/init.rb +2 -0
  23. data/lib/riemann/babbler/plugins/helpers/rest.rb +28 -0
  24. data/lib/riemann/babbler/plugins/helpers/shell.rb +37 -0
  25. data/lib/riemann/babbler/plugins/http.rb +4 -6
  26. data/lib/riemann/babbler/plugins/la.rb +11 -3
  27. data/lib/riemann/babbler/plugins/mdadm.rb +10 -10
  28. data/lib/riemann/babbler/plugins/mega_cli.rb +2 -2
  29. data/lib/riemann/babbler/plugins/memory.rb +21 -17
  30. data/lib/riemann/babbler/plugins/net.rb +7 -5
  31. data/lib/riemann/babbler/plugins/net_stat.rb +5 -5
  32. data/lib/riemann/babbler/plugins/nginx.rb +2 -2
  33. data/lib/riemann/babbler/plugins/pgsql.rb +13 -13
  34. data/lib/riemann/babbler/plugins/runit.rb +6 -7
  35. data/lib/riemann/babbler/plugins/status_file.rb +4 -4
  36. data/lib/riemann/babbler/plugins/tw_cli.rb +5 -5
  37. data/lib/riemann/babbler/responder.rb +45 -0
  38. data/lib/riemann/babbler/sender.rb +102 -0
  39. data/lib/riemann/babbler/version.rb +2 -2
  40. data/lib/riemann/babbler.rb +8 -175
  41. data/riemann-babbler.gemspec +30 -26
  42. metadata +39 -38
  43. data/config.yml +0 -72
  44. data/lib/riemann/babbler/plugins/dummy.rb +0 -12
  45. data/lib/riemann/babbler/start.rb +0 -159
  46. data/lib/riemann/babbler/support/errors.rb +0 -3
  47. data/lib/riemann/babbler/support/monkey_patches.rb +0 -42
  48. data/lib/riemann/babbler/support/plugin_helpers.rb +0 -104
  49. data/lib/riemann/babbler/support/responder.rb +0 -29
  50. data/spec/config.yml +0 -15
  51. data/spec/default.rb +0 -61
data/.gitignore CHANGED
@@ -2,3 +2,5 @@ pkg/
2
2
  .idea
3
3
  .rvmrc
4
4
  *.swp
5
+ .bundle
6
+ vendor
data/Gemfile CHANGED
@@ -1,18 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'riemann-client'
4
- gem 'configatron'
5
- gem 'logger'
6
- gem 'trollop'
7
- gem 'sys-filesystem'
8
- gem 'rest-client'
9
- gem 'net-ping'
10
- gem 'file-tail'
11
- gem 'sys-proctable'
12
- gem 'net-http-server'
13
-
14
- gem 'rspec'
15
- gem 'rake'
16
-
17
- gem 'pry'
18
- gem 'awesome_print'
3
+ # Specify your gem's dependencies in riemann-babbler.gemspec
4
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,50 +1,46 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ riemann-babbler (2.0.0pre1)
5
+ configatron
6
+ docile
7
+ net-http-server
8
+ rest-client
9
+ riemann-client
10
+ sys-filesystem
11
+ trollop
12
+
1
13
  GEM
2
14
  remote: https://rubygems.org/
3
15
  specs:
4
- awesome_print (1.1.0)
5
- beefcake (0.3.7)
16
+ beefcake (0.4.0)
6
17
  blankslate (2.1.2.4)
7
18
  coderay (1.0.9)
8
- configatron (2.10.0)
19
+ configatron (2.13.0)
9
20
  yamler (>= 0.1.0)
10
- diff-lcs (1.2.2)
11
- ffi (1.4.0)
12
- file-tail (1.0.12)
13
- tins (~> 0.5)
14
- logger (1.2.8)
15
- method_source (0.8.1)
16
- mime-types (1.21)
21
+ docile (1.1.0)
22
+ ffi (1.9.0)
23
+ method_source (0.8.2)
24
+ mime-types (1.25)
17
25
  mtrc (0.0.4)
18
26
  net-http-server (0.2.2)
19
27
  parslet (~> 1.0)
20
- net-ping (1.6.0)
21
- ffi (>= 1.0.0)
22
28
  parslet (1.5.0)
23
29
  blankslate (~> 2.0)
24
- pry (0.9.12)
30
+ pry (0.9.12.2)
25
31
  coderay (~> 1.0.5)
26
32
  method_source (~> 0.8)
27
33
  slop (~> 3.4)
28
- rake (10.0.4)
34
+ rake (10.1.0)
29
35
  rest-client (1.6.7)
30
36
  mime-types (>= 1.16)
31
- riemann-client (0.2.1)
37
+ riemann-client (0.2.2)
32
38
  beefcake (>= 0.3.5)
33
39
  mtrc (>= 0.0.4)
34
40
  trollop (>= 1.16.2)
35
- rspec (2.13.0)
36
- rspec-core (~> 2.13.0)
37
- rspec-expectations (~> 2.13.0)
38
- rspec-mocks (~> 2.13.0)
39
- rspec-core (2.13.1)
40
- rspec-expectations (2.13.0)
41
- diff-lcs (>= 1.1.3, < 2.0)
42
- rspec-mocks (2.13.0)
43
- slop (3.4.3)
44
- sys-filesystem (1.1.0)
41
+ slop (3.4.6)
42
+ sys-filesystem (1.1.1)
45
43
  ffi
46
- sys-proctable (0.9.3)
47
- tins (0.8.0)
48
44
  trollop (2.0)
49
45
  yamler (0.1.0)
50
46
 
@@ -52,17 +48,7 @@ PLATFORMS
52
48
  ruby
53
49
 
54
50
  DEPENDENCIES
55
- awesome_print
56
- configatron
57
- file-tail
58
- logger
59
- net-http-server
60
- net-ping
51
+ bundler (~> 1.3)
61
52
  pry
62
53
  rake
63
- rest-client
64
- riemann-client
65
- rspec
66
- sys-filesystem
67
- sys-proctable
68
- trollop
54
+ riemann-babbler!
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Vasiliev Dmitry
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -8,14 +8,24 @@ gem install riemann-babbler
8
8
  ### Use
9
9
  ```
10
10
  $ riemann-babbler --help
11
- Riemann-babbler is plugin manager for riemann-tools.
11
+ Riemann-babbler is tool for monitoring with riemann.
12
12
 
13
13
  Usage:
14
14
  riemann-babbler [options]
15
15
  where [options] are:
16
- --config, -c: Config file (default: /etc/riemann-babbler/config.yml)
17
- --version, -v: Print version and exit
18
- --help, -h: Show this message
16
+ --config, -c <s>: Config file (default: /etc/riemann-babbler/config.yml)
17
+ --host, -h <s>: Riemann host (default: 127.0.0.1)
18
+ --port, -p <i>: Riemann port (default: 5555)
19
+ --timeout, -t <i>: Riemann timeout (default: 5)
20
+ --fqdn, --no-fqdn, -f: Use fqdn for event hostname (default: true)
21
+ --ttl, -l <i>: TTL for events (default: 60)
22
+ --interval, -i <i>: Seconds between updates (default: 60)
23
+ --log-level, -o <s>: Level log (default: DEBUG)
24
+ --plugins-directory, -u <s>: Directory for plugins (default: /usr/share/riemann-babbler/plugins)
25
+ --tcp, --no-tcp: Use TCP transport instead of UDP (improves reliability, slight overhead. (Default: true)
26
+ --responder-port, -r <i>: Port to bind responder (default: 55755)
27
+ --version, -v: Print version and exit
28
+ --help, -e: Show this message
19
29
  ```
20
30
 
21
31
  ### Config
@@ -27,14 +37,6 @@ riemann:
27
37
  tags:
28
38
  - prod
29
39
  - web
30
- suffix: ".testing"
31
- preffix: "prefix"
32
-
33
- plugins:
34
- dirs:
35
- - /etc/riemann/plugins # load all rb files in dirs
36
- files:
37
- - /var/lib/riemann-plugins/test.rb # and custom load somefile
38
40
  ```
39
41
  ##### Config yml for custom plugin
40
42
  ```yaml
@@ -51,7 +53,7 @@ plugins:
51
53
  ### Custom Plugin
52
54
  #### Example 1
53
55
  ```ruby
54
- class Riemann::Babbler::Awesomeplugin < Riemann::Babbler
56
+ class Riemann::Babbler::Plugin::AwesomePlugin < Riemann::Babbler::Plugin
55
57
 
56
58
  def init
57
59
  plugin.set_default(:service, 'awesome plugin' )
@@ -70,7 +72,7 @@ end
70
72
  ```
71
73
  #### Example 2
72
74
  ```ruby
73
- class Riemann::Babbler::Awesomeplugin < Riemann::Babbler
75
+ class Riemann::Babbler::Plugin::AwesomePlugin < Riemann::Babbler::Plugin
74
76
 
75
77
  def init
76
78
  plugin.set_default(:service, 'awesome plugin' )
@@ -94,9 +96,9 @@ class Riemann::Babbler::Awesomeplugin < Riemann::Babbler
94
96
  status << {
95
97
  :service => plugin.service + " cmd2",
96
98
  :metric => shell plugin.cmd2, # shell - helper
97
- :as_diff => true # report as diffencial: current - last
99
+ :as_diff => true # report as differential: current - last
98
100
  }
99
101
  status
100
102
  end
101
103
  end
102
- ```
104
+ ```
data/bin/riemann-babbler CHANGED
@@ -2,24 +2,44 @@
2
2
  # coding: utf-8
3
3
 
4
4
  require 'trollop'
5
- require 'configatron'
5
+ require 'yaml'
6
+ require_relative '../lib/riemann/babbler'
7
+ require_relative '../lib/riemann/babbler/plugin'
6
8
 
7
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
- require 'riemann/babbler/version'
9
- require 'riemann/babbler/start'
9
+ include Riemann::Babbler::Logging
10
+ include Riemann::Babbler::Options
10
11
 
11
- opts = Trollop::options do
12
+ cmd_opts = Trollop::options do
12
13
  version "Riemann babbler #{Riemann::Babbler::VERSION}"
13
14
  banner <<-EOS
14
- Riemann-babbler is plugin manager for riemann-tools.
15
+ Riemann-babbler is tool for monitoring with riemann.
15
16
 
16
17
  Usage:
17
- riemann-babbler [options]
18
+ riemann-babbler [options]
18
19
  where [options] are:
19
- EOS
20
+ EOS
20
21
 
21
22
  opt :config, 'Config file', :default => '/etc/riemann-babbler/config.yml'
23
+ opt :host, 'Riemann host', :default => '127.0.0.1'
24
+ opt :port, 'Riemann port', :default => 5555
25
+ opt :timeout, 'Riemann timeout', :default => 5
26
+ #todo: opt :event_hostname, 'Event hostname', :type => String
27
+ opt :fqdn, 'Use fqdn for event hostname', :default => true
28
+ opt :ttl, 'TTL for events', :default => 60
29
+ opt :interval, 'Seconds between updates', :default => 60
30
+ opt :log_level, 'Level log', :default => 'DEBUG'
31
+ #todo: opt :log_output, 'Directions to puts your log', :default => STDOUT
32
+ #todo: opt :log_format, 'Log format', :default => '%Y-%m-%d %H:%M:%S'
33
+ opt :plugins_directory, 'Directory for plugins', :default => '/usr/share/riemann-babbler/plugins'
34
+ opt :tcp, 'Use TCP transport instead of UDP (improves reliability, slight overhead.', :default => true
35
+ opt :responder_port, 'Port to bind responder', :default => 55755
22
36
  end
23
37
 
24
- babbler = Riemann::Babbler::Starter.new(opts, configatron)
25
- babbler.start!
38
+ # load current settings
39
+ opts.configure_from_hash({ :riemann => cmd_opts })
40
+ @@logger.level = Logger.const_get(opts.riemann.log_level) #todo: to hard
41
+ merge_config(opts.riemann.config)
42
+
43
+ # start
44
+ Riemann::Babbler::Responder.new.run!
45
+ Riemann::Babbler::PluginLoader.new(Riemann::Babbler::Sender.new).run!
@@ -0,0 +1,13 @@
1
+ module Riemann
2
+ module Babbler
3
+
4
+ module Errors
5
+ RESOLV_RIEMANN_SERVER = 1
6
+ INIT_CONNECT = 2
7
+ CONNECTION_PROBLEM = 3
8
+ end
9
+
10
+ end
11
+ end
12
+
13
+
@@ -0,0 +1,36 @@
1
+ require 'logger'
2
+
3
+ module Riemann
4
+ module Babbler
5
+
6
+ module Logging
7
+
8
+ @levels = { 'DEBUG' => 0, 'INFO' => 1, 'WARN' => 2, 'ERROR' => 3, 'FATAL' => 4 }
9
+ @@logger = Logger.new(STDOUT) #todo: opts
10
+
11
+ def log(log_level, message, method = nil)
12
+ speaker = get_logger_speaker
13
+ speaker = speaker + "##{method}" unless method.nil?
14
+ @@logger.send(log_level.to_sym, " [#{speaker}] #{message}")
15
+ end
16
+
17
+ def set_logger_speaker(speaker)
18
+ @logger_speaker = speaker
19
+ end
20
+
21
+ def get_logger_speaker
22
+ if @logger_speaker.nil?
23
+ self.class == Class ? "C: #{self.to_s}" : "I: #{self.class.to_s}"
24
+ else
25
+ @logger_speaker
26
+ end
27
+ end
28
+
29
+ def self.included(base)
30
+ base.extend(self)
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
@@ -1,3 +1,28 @@
1
+ module Beefcake
2
+ class Buffer
3
+
4
+ def initialize(buf='')
5
+ if buf.respond_to?(:force_encoding)
6
+ self.buf = buf.force_encoding('BINARY')
7
+ else
8
+ self.buf = buf
9
+ end
10
+ end
11
+
12
+ def append_string(s)
13
+ append_uint64(s.length)
14
+ if s.respond_to?(:force_encoding)
15
+ self << s.force_encoding('BINARY')
16
+ else
17
+ self << s
18
+ end
19
+ end
20
+
21
+ alias :append_bytes :append_string
22
+
23
+ end
24
+ end
25
+
1
26
  # https://raw.github.com/Offirmo/hash-deep-merge/master/lib/hash_deep_merge.rb
2
27
  class Hash
3
28
 
@@ -13,36 +38,20 @@ class Hash
13
38
 
14
39
  protected
15
40
 
16
- # better, recursive, preserving method
17
- # OK OK this is not the most efficient algorithm,
18
- # but at last it's *perfectly clear and understandable*
19
- # so fork and improve if you need 5% more speed, ok ?
20
41
  def internal_deep_merge!(source_hash, specialized_hash)
21
-
22
- #puts "starting deep merge..."
23
-
24
42
  specialized_hash.each_pair do |rkey, rval|
25
- #puts " potential replacing entry : " + rkey.inspect
26
-
27
43
  if source_hash.has_key?(rkey) then
28
- #puts " found potentially conflicting entry for #{rkey.inspect} : #{rval.inspect}, will merge :"
29
44
  if rval.is_a?(Hash) and source_hash[rkey].is_a?(Hash) then
30
- #puts " recursing..."
31
45
  internal_deep_merge!(source_hash[rkey], rval)
32
46
  elsif rval == source_hash[rkey] then
33
- #puts " same value, skipping."
34
47
  else
35
- #puts " replacing."
36
48
  source_hash[rkey] = rval
37
49
  end
38
50
  else
39
- #puts " found new entry #{rkey.inspect}, adding it..."
40
51
  source_hash[rkey] = rval
41
52
  end
42
53
  end
43
54
 
44
- #puts "deep merge done."
45
-
46
55
  source_hash
47
56
  end
48
57
  end
@@ -0,0 +1,43 @@
1
+ require 'configatron'
2
+
3
+ module Riemann
4
+ module Babbler
5
+
6
+ module Options
7
+
8
+ @@configatron = configatron
9
+
10
+ def opts
11
+ @@configatron
12
+ end
13
+
14
+ #@return
15
+ def merge_config(file)
16
+ config_from_file = if File.exist?(file)
17
+ YAML.load_file(file).to_hash
18
+ else
19
+ log :error, "Can't load config file #{file}"
20
+ Hash.new
21
+ end
22
+ config_default = opts.to_hash
23
+ result_config = config_default.deep_merge(config_from_file)
24
+ opts.configure_from_hash(result_config)
25
+ end
26
+
27
+ def name_to_underscore(name = 'Riemann::Babbler::Plugin::TwCli')
28
+ name.split('::').last.gsub(/(\p{Lower})(\p{Upper})/, "\\1_\\2").downcase
29
+ end
30
+
31
+ def underscore_to_name(underscore = 'tw_cli')
32
+ underscore.split('_').map { |part| part.capitalize }.join('')
33
+ end
34
+
35
+ def self.included(base)
36
+ Configatron.log.level = Logger::FATAL
37
+ base.extend(self)
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,154 @@
1
+ #encoding: utf-8
2
+
3
+ require 'riemann/babbler/plugins/helpers/init'
4
+
5
+ module Riemann
6
+ module Babbler
7
+
8
+ module State
9
+ OK = 'ok'
10
+ WARNING = 'warning'
11
+ CRITICAL = 'critical'
12
+ end
13
+
14
+ class Plugin
15
+
16
+ include Riemann::Babbler::Logging
17
+ include Riemann::Babbler::Errors
18
+ include Riemann::Babbler::Options
19
+ include Riemann::Babbler::Plugins::Helpers
20
+
21
+ def self.registered_plugins
22
+ @plugins ||= []
23
+ end
24
+
25
+ def self.inherited(klass)
26
+ registered_plugins << klass
27
+ end
28
+
29
+ attr_reader :riemann, :plugin_name, :plugin, :errors
30
+
31
+ def initialize(riemann)
32
+ @riemann = riemann
33
+ @storage = Hash.new
34
+ @plugin_name = name_to_underscore(self.class.name)
35
+ @plugin = opts.plugins.send(plugin_name)
36
+ @errors = opts.errors.send(plugin_name)
37
+ set_default
38
+ init
39
+ end
40
+
41
+ def set_default
42
+ plugin.set_default(:interval, opts.riemann.interval)
43
+ plugin.timeout = (plugin.interval * 2).to_f/3
44
+ errors.last_error = nil
45
+ errors.last_error_at = nil
46
+ errors.has_last_error = false
47
+ errors.reported = true
48
+ plugin_no_error!
49
+ errors.count = 0
50
+ end
51
+
52
+ def init
53
+ # nothing to do
54
+ end
55
+
56
+ def run_plugin
57
+ if plugin.run.nil?
58
+ true
59
+ else
60
+ plugin.run ? true : false
61
+ end
62
+ end
63
+
64
+ def tick
65
+ posted_array = collect
66
+ posted_array = posted_array.class == Array ? posted_array : [posted_array]
67
+ posted_array.uniq.each { |event| report event }
68
+ end
69
+
70
+ def report(event)
71
+ report_with_diff(event) and return if event[:as_diff]
72
+ event[:metric] = event[:metric].round(2) if event[:metric].kind_of? Float
73
+ event[:state] = get_state(event)
74
+ riemann << event
75
+ end
76
+
77
+ def report_with_diff(event)
78
+ current_metric = event[:metric]
79
+ old_metric = @storage[event[:service]]
80
+ if old_metric && current_metric + old_metric < 2**64
81
+ event[:metric] = current_metric - old_metric
82
+ event.delete(:as_diff)
83
+ report(event)
84
+ end
85
+ @storage[event[:service]] = current_metric
86
+ end
87
+
88
+ #@return state
89
+ def get_state(event)
90
+ return event[:state] if event[:state]
91
+ metric = event[:metric].to_f
92
+ return State::CRITICAL if metric.nil? #todo: неправильно здесь возврашать nil, это ошибка плагина!!!
93
+ warning = plugin.states.warning.nil? ? nil : plugin.states.warning
94
+ critical = plugin.states.critical.nil? ? nil : plugin.states.critical
95
+ return State::OK if (warning || critical).nil?
96
+ if warning && critical
97
+ return case
98
+ when metric.between?(warning, critical)
99
+ State::WARNING
100
+ when metric > warning
101
+ State::CRITICAL
102
+ else
103
+ State::OK
104
+ end
105
+ end
106
+ if warning
107
+ return (metric >= warning) ? State::WARNING : State::OK
108
+ end
109
+ if critical
110
+ return (metric >= critical) ? State::CRITICAL : State::OK
111
+ end
112
+ end
113
+
114
+ def plugin_error!(msg)
115
+ errors.count += 1
116
+ log :error, "#{plugin.service} error num #{errors.count}:\n #{msg}"
117
+ errors.has_last_error = true
118
+ errors.reported = false
119
+ errors.last_error_at = Time.now
120
+ errors.last_error = "#{msg}"
121
+ end
122
+
123
+ def plugin_no_error!
124
+ if errors.has_last_error
125
+ log :error, "#{plugin.service} error num #{errors.count} fixed"
126
+ errors.has_last_error = false
127
+ end
128
+ end
129
+
130
+ # Main method
131
+ def run!
132
+ return 0 unless run_plugin
133
+ t0 = Time.now
134
+ loop do
135
+
136
+ begin
137
+ Timeout::timeout(plugin.interval) { tick }
138
+ rescue TimeoutError
139
+ plugin_error!('Timeout plugin execution')
140
+ rescue => e
141
+ plugin_error!("Plugin '#{plugin_name}' has a error.\n #{e.class}: #{e}\n #{e.backtrace.join("\n")}")
142
+ else
143
+ plugin_no_error!
144
+ end
145
+
146
+ sleep(plugin.interval - ((Time.now - t0) % plugin.interval))
147
+ end
148
+
149
+ end
150
+
151
+ end
152
+
153
+ end
154
+ end
@@ -0,0 +1,86 @@
1
+ module Riemann
2
+ module Babbler
3
+ class PluginLoader
4
+
5
+ include Riemann::Babbler::Logging
6
+ include Riemann::Babbler::Options
7
+
8
+ AUTO_START = [
9
+ 'cpu',
10
+ 'cpu_fan',
11
+ 'cpu_temp',
12
+ 'disk',
13
+ 'disk_stat',
14
+ 'exim4',
15
+ 'la',
16
+ 'mdadm',
17
+ 'mega_cli',
18
+ 'memory',
19
+ 'net',
20
+ 'runit',
21
+ 'tw_cli',
22
+ 'errors_reporter'
23
+ ].freeze
24
+
25
+ attr_accessor :sender
26
+
27
+ def initialize(riemann)
28
+ @sender = riemann
29
+ end
30
+
31
+ def all_available_plugins
32
+ default_plugins_dir = File.expand_path('../plugins/', __FILE__)
33
+ plugins = []
34
+ Dir.glob(default_plugins_dir + '/*.rb') do |file|
35
+ plugins << file
36
+ end
37
+ if Dir.exist? opts.riemann.plugins_directory
38
+ Dir.glob(opts.riemann.plugins_directory + '/*.rb') do |file|
39
+ plugins << file
40
+ end
41
+ else
42
+ log :error, "Directory doesn't exists: #{opts.riemann.plugins_directory}"
43
+ end
44
+ plugins
45
+ end
46
+
47
+ def require_all_plugins
48
+ Riemann::Babbler::Plugin.registered_plugins.clear
49
+ all_available_plugins.each { |file| require file }
50
+ log :debug, "Require plugins: #{Riemann::Babbler::Plugin.registered_plugins}"
51
+ # load parent
52
+ opts.plugins.to_hash.each do |plugin_name, plugin_opts|
53
+ next if plugin_opts.nil?
54
+ next unless plugin_opts.kind_of?(Hash)
55
+ if plugin_opts.has_key? "parent"
56
+ klass = Class.new(underscore_to_name(plugin_name))
57
+ klass.send(:title, underscore_to_name(plugin_opts[:parent]).to_sym)
58
+ Riemann::Babbler::Plugin.registered_plugins << klass
59
+ end
60
+ end
61
+ end
62
+
63
+ def run!
64
+ plugin_names_to_run = AUTO_START + opts.plugins.to_hash.keys
65
+ require_all_plugins
66
+ started_plugins = []
67
+ Riemann::Babbler::Plugin.registered_plugins.each do |klass|
68
+ if plugin_names_to_run.include? name_to_underscore(klass.to_s)
69
+ started_plugins << klass
70
+ end
71
+ end
72
+ plugin_threads = started_plugins.map do |plugin|
73
+ Thread.new {
74
+ log :unknown, "Start plugin #{plugin}"
75
+ plugin.new(sender).run!
76
+ }
77
+ end
78
+ Signal.trap 'TERM' do
79
+ plugin_threads.each(&:kill)
80
+ end
81
+ plugin_threads.each(&:join)
82
+ end
83
+
84
+ end
85
+ end
86
+ end