riemann-babbler 0.9.7 → 0.9.8

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.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format nested --fail-fast
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language:
2
+ - ruby
3
+ rvm:
4
+ - 1.9.3
5
+ script: "bundle exec rspec spec/default.rb"
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gem 'riemann-client'
4
4
  gem 'configatron'
data/Gemfile.lock CHANGED
@@ -1,5 +1,5 @@
1
1
  GEM
2
- remote: http://rubygems.org/
2
+ remote: https://rubygems.org/
3
3
  specs:
4
4
  awesome_print (1.1.0)
5
5
  beefcake (0.3.7)
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://travis-ci.org/vadv/riemann-babbler.png)](https://travis-ci.org/vadv/riemann-babbler)
2
+
1
3
  ### Install
2
4
  ```
3
5
  gem install riemann-babbler
data/bin/riemann-babbler CHANGED
@@ -2,15 +2,10 @@
2
2
  #encoding: utf-8
3
3
 
4
4
  require 'trollop'
5
- require 'yaml'
6
5
  require 'configatron'
7
- require 'logger'
8
- require 'resolv'
9
- require 'sequel'
10
- require 'socket'
11
6
 
12
7
  require File.expand_path('../../lib/riemann/version', __FILE__)
13
- require File.expand_path('../../lib/start_helpers', __FILE__)
8
+ require File.expand_path('../../lib/start', __FILE__)
14
9
 
15
10
  opts = Trollop::options do
16
11
  version "Riemann babbler #{Riemann::Babbler::VERSION}"
@@ -25,14 +20,5 @@ EOS
25
20
  opt :config, 'Config file', :default => '/etc/riemann-babbler/config.yml'
26
21
  end
27
22
 
28
- # logger
29
- logger = Logger.new(STDOUT)
30
-
31
- # start_helpers
32
- merge_config( logger, opts, configatron )
33
- set_logger_lvl( logger, configatron )
34
- load_plugins( configatron )
35
- load_gems_plugins( configatron )
36
- riemann = get_riemann( configatron, logger )
37
- load_parent( configatron )
38
- start_plugins( Riemann::Babbler.registered_plugins, riemann, logger, configatron )
23
+ babbler = Riemann::Babbler::Starter.new(opts, configatron)
24
+ babbler.start!
@@ -1,11 +1,14 @@
1
1
  #encoding: utf-8
2
2
 
3
- require File.expand_path('../plugin_helpers', __FILE__)
3
+ require File.expand_path('../support/plugin_helpers', __FILE__)
4
4
  require 'riemann/client'
5
5
  require 'open3'
6
6
  require 'timeout'
7
7
  require 'rest_client'
8
- require File.expand_path('../monkey_patches', __FILE__)
8
+ require 'socket'
9
+ require 'net/ping'
10
+ require 'sequel'
11
+ require File.expand_path('../support/monkey_patches', __FILE__)
9
12
 
10
13
 
11
14
  # Базовое описание плагина
@@ -33,7 +36,6 @@ module Riemann
33
36
  @hostname = get_hostname
34
37
  init
35
38
  plugin.set_default(:interval, configatron.riemann.interval)
36
- run
37
39
  end
38
40
 
39
41
  # Доступ к конфигу определенного плагина
@@ -1,7 +1,13 @@
1
1
  class Riemann::Babbler::Dummy < Riemann::Babbler
2
2
 
3
3
  def collect
4
- { :service => plugin.service , :state => 'ok' }
4
+ if tcp_port_aviable?(configatron.riemann.host, configatron.riemann.port)
5
+ logger.error "Riemann state 'ok' host: #{configatron.riemann.host}, port #{configatron.riemann.port}, proto tcp"
6
+ []
7
+ else
8
+ logger.error "Can't access to riemann host: #{configatron.riemann.host}, port #{configatron.riemann.port}, proto tcp"
9
+ end
10
+ Array.new
5
11
  end
6
12
 
7
13
  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
@@ -4,8 +4,8 @@ class Riemann::Babbler::Netstat < Riemann::Babbler
4
4
  plugin.set_default(:service, 'netstat')
5
5
  plugin.set_default(:interval, 60)
6
6
  plugin.set_default(:port, 80)
7
- #plugin.states.set_default(:warning, 300)
8
- #plugin.states.set_default(:critical, 400)
7
+ plugin.states.set_default(:warning, 300)
8
+ plugin.states.set_default(:critical, 400)
9
9
  end
10
10
 
11
11
  def collect
@@ -0,0 +1,78 @@
1
+ #encoding: utf-8
2
+
3
+ module Riemann
4
+ class Babbler
5
+
6
+ def helper_error(msg = 'Unknown helper error')
7
+ report({
8
+ :service => plugin.service,
9
+ :state => 'critical',
10
+ :description => msg
11
+ })
12
+ end
13
+
14
+ def plugin_timeout
15
+ ( plugin.interval * 2 ).to_f/3
16
+ end
17
+
18
+ # хэлпер для парса stdout+stderr и exit status
19
+ def shell(*cmd)
20
+ exit_status=nil
21
+ err=nil
22
+ out=nil
23
+ begin
24
+ Timeout::timeout(plugin_timeout) {
25
+ Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thread|
26
+ err = stderr.gets(nil)
27
+ out = stdout.gets(nil)
28
+ [stdin, stdout, stderr].each{|stream| stream.send('close')}
29
+ exit_status = wait_thread.value
30
+ end
31
+ }
32
+ rescue => e
33
+ helper_error "#{e.class} #{e}\n#{e.backtrace.join "\n"}"
34
+ end
35
+ if exit_status.to_i > 0
36
+ err = err.chomp if err
37
+ helper_error(err)
38
+ elsif out
39
+ return out.strip
40
+ else
41
+ # статус 0, вывода stdout нет
42
+ ''
43
+ end
44
+ end
45
+
46
+ def tcp_port_aviable?(ip, port)
47
+ begin
48
+ Timeout::timeout(plugin_timeout) do
49
+ begin
50
+ s = TCPSocket.new(ip, port)
51
+ s.close
52
+ return true
53
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
54
+ return false
55
+ end
56
+ end
57
+ rescue Timeout::Error
58
+ end
59
+ return false
60
+ end
61
+
62
+ # http rest
63
+ def rest_get(url)
64
+ begin
65
+ Timeout::timeout(plugin_timeout) do
66
+ begin
67
+ RestClient.get url
68
+ rescue
69
+ helper_error("Get from url: #{url} failed")
70
+ end
71
+ end
72
+ rescue Timeout::Error
73
+ helper_error("Get from url: #{url}, timeout error")
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -1,5 +1,5 @@
1
1
  module Riemann
2
2
  class Babbler
3
- VERSION = '0.9.7'
3
+ VERSION = '0.9.8'
4
4
  end
5
5
  end
data/lib/start.rb ADDED
@@ -0,0 +1,158 @@
1
+ require 'yaml'
2
+ require 'logger'
3
+ require 'resolv'
4
+
5
+ require File.expand_path('../riemann/babbler/support/deep_merge', __FILE__)
6
+ require File.expand_path('../riemann/babbler/plugin', __FILE__)
7
+
8
+ class Riemann::Babbler::Starter
9
+
10
+ attr_reader :logger
11
+ attr_reader :opts
12
+ attr_reader :riemann
13
+ attr_reader :config
14
+
15
+ def initialize(opts, configatron)
16
+ @opts = opts
17
+ @config = configatron
18
+ Configatron.log.level = Logger::FATAL
19
+ Gem::Deprecate.skip = true
20
+ end
21
+
22
+ def logger
23
+ @logger ||= Logger.new(STDOUT)
24
+ end
25
+
26
+ def start!
27
+ merge_config
28
+ set_logger_lvl
29
+ load_plugins
30
+ start_plugins!
31
+ end
32
+
33
+ def merge_config
34
+ config_file = if File.exist?( opts[:config] )
35
+ YAML.load_file( opts[:config] ).to_hash
36
+ else
37
+ logger.warn "Can't load config file #{opts[:config]}"
38
+ Hash.new
39
+ end
40
+ config_default = YAML.load_file( File.expand_path('../../config.yml', __FILE__) )
41
+ config_from_file = config_default.deep_merge( config_file )
42
+ config.configure_from_hash config_from_file
43
+ end
44
+
45
+ def set_logger_lvl
46
+ case config.logger.level
47
+ when 'INFO'
48
+ logger.level = Logger::INFO
49
+ when 'WARN'
50
+ logger.level = Logger::WARN
51
+ when 'ERROR'
52
+ logger.level = Logger::ERROR
53
+ when 'FATAL'
54
+ logger.level = Logger::FATAL
55
+ when 'UNKNOWN'
56
+ logger.level = Logger::UNKNOWN
57
+ else
58
+ logger.level = Logger::DEBUG
59
+ end
60
+ end
61
+
62
+ def load_plugins
63
+ plugins = Array.new
64
+ default_plugins_dir = File.expand_path('../riemann/babbler/plugins/', __FILE__)
65
+ Dir.glob( default_plugins_dir + '/*.rb') do |file|
66
+ plugins << file
67
+ end
68
+
69
+ unless config.plugins.dirs.nil?
70
+ config.plugins.dirs.each do |dir|
71
+ next unless Dir.exist? dir
72
+ Dir.glob( dir + '/*.rb') do |file|
73
+ plugins << file
74
+ end
75
+ end
76
+ end
77
+
78
+ unless config.plugins.files.nil?
79
+ config.plugins.files.each do |file|
80
+ plugins << file
81
+ end
82
+ end
83
+ plugins.each { |plugin| require plugin }
84
+ load_gems_plugins
85
+ load_parent
86
+ end
87
+
88
+ def load_gems_plugins
89
+ plugins = Array.new
90
+ begin
91
+ Gem.source_index.each do |gem|
92
+ plugin_name = gem[1].to_s.scan(/\s+name=(.+)\s+/)[0][0]
93
+ plugins << plugin_name.gsub('-','/') if plugin_name.include? 'riemann-babbler-plugin-'
94
+ end
95
+ rescue
96
+ logger.error "Can't find gems riemann-babbler-plugin-"
97
+ end
98
+ plugins.each { |plugin| require plugin }
99
+ end
100
+
101
+ def load_parent
102
+ config.to_hash[:plugins].each do |plugin, plugin_opts|
103
+ next if plugin_opts.nil?
104
+ next unless plugin_opts.kind_of? Hash
105
+ create_class(plugin.capitalize, plugin_opts[:parent].capitalize) if plugin_opts.has_key? :parent
106
+ end
107
+ end
108
+
109
+ def create_class(new_class, parent_class)
110
+ cmd = "class Riemann::Babbler::#{new_class} < Riemann::Babbler::#{parent_class}; end;"
111
+ cmd += "Riemann::Babbler.registered_plugins << Riemann::Babbler::#{new_class}"
112
+ eval(cmd)
113
+ end
114
+
115
+ def riemann
116
+ @riemann ||= get_riemann
117
+ end
118
+
119
+ def get_riemann
120
+ begin
121
+ riemann_ip = Resolv.new.getaddress(config.riemann.host)
122
+ riemann = Riemann::Client.new(
123
+ :host => riemann_ip,
124
+ :port => config.riemann.port
125
+ )
126
+ riemann = ( config.riemann.proto == 'tcp' ) ? riemann.tcp : riemann
127
+ rescue
128
+ logger.fatal "Can't resolv riemann host: #{config.riemann.host}"
129
+ sleep 5
130
+ retry
131
+ end
132
+ riemann
133
+ end
134
+
135
+ def started_plugins
136
+ registered_plugins = Riemann::Babbler.registered_plugins.dup
137
+ run_only = Array.new
138
+ config.plugins.to_hash.keys.each { |key| run_only << key.to_s }
139
+ registered_plugins.delete_if {|plugin| ! run_only.include? plugin.to_s.split('::').last.downcase }
140
+ registered_plugins
141
+ end
142
+
143
+ def start_plugins!
144
+ plugin_threads = started_plugins.map do |plugin|
145
+ Thread.new {
146
+ plugin.new( config, logger, riemann ).run
147
+ }
148
+ end
149
+
150
+ # plugin control
151
+ Signal.trap 'TERM' do
152
+ plugin_threads.each( &:kill )
153
+ end
154
+
155
+ plugin_threads.each( &:join )
156
+ end
157
+
158
+ end
data/spec/config.yml ADDED
@@ -0,0 +1,15 @@
1
+ riemann:
2
+ host: hostname_does_not_exists
3
+ port: 5555
4
+ proto: auto # auto use tcp + udp(max size 16384), tcp - tcp only
5
+ interval: 60 # update interval for all plugins
6
+ use_fqdn: true
7
+
8
+ logger:
9
+ level: FATAL
10
+
11
+ plugins:
12
+ dummy2:
13
+ parent: dummy
14
+ run: false
15
+ interval: 2000
data/spec/default.rb ADDED
@@ -0,0 +1,60 @@
1
+ #encoding: utf-8
2
+
3
+ require 'riemann/babbler/plugin'
4
+ require 'start'
5
+ require 'configatron'
6
+
7
+ opts = Hash.new
8
+ opts[:config] = File.expand_path('../config.yml', __FILE__)
9
+
10
+ babbler = Riemann::Babbler::Starter.new(opts, configatron)
11
+
12
+ describe Riemann::Babbler do
13
+
14
+ it 'Merge config' do
15
+ babbler.merge_config
16
+ configatron.riemann.host.should eq 'hostname_does_not_exists'
17
+ end
18
+
19
+ it 'Set logger lvl' do
20
+ babbler.set_logger_lvl
21
+ babbler.logger.level.should eq 4
22
+ end
23
+
24
+ it 'Load plugins' do
25
+ babbler.load_plugins
26
+ Riemann::Babbler.registered_plugins.should include( Riemann::Babbler::Dummy )
27
+ end
28
+
29
+ it 'Started plugins' do
30
+ babbler.started_plugins.should include( Riemann::Babbler::Dummy )
31
+ end
32
+
33
+ it 'Parent plugins' do
34
+ babbler.started_plugins.should include( Riemann::Babbler::Dummy2 )
35
+ end
36
+
37
+ it 'Custom parent plugin start' do
38
+ dummyplugin = Riemann::Babbler::Dummy2.new(configatron, nil, nil)
39
+ configatron.plugins.dummy2.to_hash.should include(:run => false)
40
+ dummyplugin.plugin.run.should eq false
41
+ dummyplugin.plugin.interval.should eq 2000
42
+ dummyplugin.run.should eq 0
43
+ end
44
+
45
+ it 'Shell helper' do
46
+ dummyplugin = Riemann::Babbler::Dummy2.new(configatron, nil, nil)
47
+ dummyplugin.shell("echo 'a' | wc -l").to_i.should eq 1
48
+ end
49
+
50
+ it 'RestGet helper' do
51
+ dummyplugin = Riemann::Babbler::Dummy2.new(configatron, nil, nil)
52
+ dummyplugin.rest_get('http://ya.ru').should include 'yandex.ru'
53
+ end
54
+
55
+ it 'TcpPortAviable helper' do
56
+ dummyplugin = Riemann::Babbler::Dummy2.new(configatron, nil, nil)
57
+ dummyplugin.tcp_port_aviable?('www.ya.ru', 80).should eq true
58
+ end
59
+
60
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riemann-babbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.7
4
+ version: 0.9.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -148,16 +148,15 @@ extensions: []
148
148
  extra_rdoc_files: []
149
149
  files:
150
150
  - .gitignore
151
+ - .rspec
152
+ - .travis.yml
151
153
  - Gemfile
152
154
  - Gemfile.lock
153
155
  - README.md
154
156
  - Rakefile
155
157
  - bin/riemann-babbler
156
158
  - config.yml
157
- - lib/deep_merge.rb
158
- - lib/riemann/babbler/monkey_patches.rb
159
159
  - lib/riemann/babbler/plugin.rb
160
- - lib/riemann/babbler/plugin_helpers.rb
161
160
  - lib/riemann/babbler/plugins/cpu.rb
162
161
  - lib/riemann/babbler/plugins/cpufan.rb
163
162
  - lib/riemann/babbler/plugins/cputemp.rb
@@ -172,9 +171,14 @@ files:
172
171
  - lib/riemann/babbler/plugins/netstat.rb
173
172
  - lib/riemann/babbler/plugins/nginx.rb
174
173
  - lib/riemann/babbler/plugins/runit.rb
174
+ - lib/riemann/babbler/support/deep_merge.rb
175
+ - lib/riemann/babbler/support/monkey_patches.rb
176
+ - lib/riemann/babbler/support/plugin_helpers.rb
175
177
  - lib/riemann/version.rb
176
- - lib/start_helpers.rb
178
+ - lib/start.rb
177
179
  - riemann-babbler.gemspec
180
+ - spec/config.yml
181
+ - spec/default.rb
178
182
  homepage: https://github.com/vadv/riemann-babbler
179
183
  licenses:
180
184
  - MIT
@@ -190,7 +194,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
190
194
  version: '0'
191
195
  segments:
192
196
  - 0
193
- hash: 1337242013675877660
197
+ hash: -440020618523197346
194
198
  required_rubygems_version: !ruby/object:Gem::Requirement
195
199
  none: false
196
200
  requirements:
@@ -203,4 +207,6 @@ rubygems_version: 1.8.25
203
207
  signing_key:
204
208
  specification_version: 3
205
209
  summary: Riemann health checker.
206
- test_files: []
210
+ test_files:
211
+ - spec/config.yml
212
+ - spec/default.rb
@@ -1,53 +0,0 @@
1
- #encoding: utf-8
2
-
3
- module Riemann
4
- class Babbler
5
-
6
- def helper_error(msg = 'Unknown helper error')
7
- report({
8
- :service => plugin.service,
9
- :state => 'critical',
10
- :description => msg
11
- })
12
- end
13
-
14
- # хэлпер для парса stdout+stderr и exit status
15
- def shell(*cmd)
16
- exit_status=nil
17
- err=nil
18
- out=nil
19
- begin
20
- timeout_shell = ( plugin.interval * 2 ).to_f/3
21
- Timeout::timeout(timeout_shell) {
22
- Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thread|
23
- err = stderr.gets(nil)
24
- out = stdout.gets(nil)
25
- [stdin, stdout, stderr].each{|stream| stream.send('close')}
26
- exit_status = wait_thread.value
27
- end
28
- }
29
- rescue => e
30
- helper_error "#{e.class} #{e}\n#{e.backtrace.join "\n"}"
31
- end
32
- if exit_status.to_i > 0
33
- err = err.chomp if err
34
- helper_error(err)
35
- elsif out
36
- return out.strip
37
- else
38
- # статус 0, вывода stdout нет
39
- ''
40
- end
41
- end
42
-
43
- # http rest
44
- def rest_get(url)
45
- begin
46
- RestClient.get url
47
- rescue
48
- helper_error("Get from url: #{url}")
49
- end
50
- end
51
-
52
- end
53
- end
data/lib/start_helpers.rb DELETED
@@ -1,121 +0,0 @@
1
- require File.expand_path('../deep_merge', __FILE__)
2
- require File.expand_path('../riemann/babbler/plugin', __FILE__)
3
-
4
- def set_logger_lvl(logger, configatron)
5
- case configatron.logger.level
6
- when 'INFO'
7
- logger.level = Logger::INFO
8
- when 'WARN'
9
- logger.level = Logger::WARN
10
- when 'ERROR'
11
- logger.level = Logger::ERROR
12
- when 'FATAL'
13
- logger.level = Logger::FATAL
14
- when 'UNKNOWN'
15
- logger.level = Logger::UNKNOWN
16
- else
17
- logger.level = Logger::DEBUG
18
- end
19
- end
20
-
21
- # merge configs
22
- def merge_config(logger, opts, configatron)
23
- config_file = if File.exist?( opts[:config] )
24
- YAML.load_file( opts[:config] ).to_hash
25
- else
26
- logger.error "Can't load config file #{opts[:config]}"
27
- Hash.new
28
- end
29
-
30
- config_default = YAML.load_file( File.expand_path('../../config.yml', __FILE__) )
31
-
32
- config = config_default.deep_merge( config_file )
33
- configatron.configure_from_hash config
34
- end
35
-
36
- # получаем список все плагинов
37
- def load_plugins(configatron)
38
- plugins = Array.new
39
- default_plugins_dir = File.expand_path('../riemann/babbler/plugins/', __FILE__)
40
- Dir.glob( default_plugins_dir + '/*.rb') do |file|
41
- plugins << file
42
- end
43
-
44
- unless configatron.plugins.dirs.nil?
45
- configatron.plugins.dirs.each do |dir|
46
- next unless Dir.exist? dir
47
- Dir.glob( dir + '/*.rb') do |file|
48
- plugins << file
49
- end
50
- end
51
- end
52
-
53
- unless configatron.plugins.files.nil?
54
- configatron.plugins.files.each do |file|
55
- plugins << file
56
- end
57
- end
58
- plugins.each { |plugin| require plugin }
59
- end
60
-
61
- def load_gems_plugins(configatron)
62
- plugins = Array.new
63
- Gem.source_index.each do |gem|
64
- plugin_name = gem[1].to_s.scan(/\s+name=(.+)\s+/)[0][0]
65
- plugins << plugin_name.gsub('-','/') if plugin_name.include? 'riemann-babbler-plugin-'
66
- end
67
- plugins.each { |plugin| require plugin }
68
- end
69
-
70
- def get_riemann(configatron, logger)
71
- begin
72
- riemann_ip = Resolv.new.getaddress(configatron.riemann.host)
73
- riemann = Riemann::Client.new(
74
- :host => riemann_ip,
75
- :port => configatron.riemann.port
76
- )
77
- riemann = ( configatron.riemann.proto == 'tcp' ) ? riemann.tcp : riemann
78
- rescue
79
- logger.error "Can't resolv riemann host: #{configatron.riemann.host}"
80
- sleep 5
81
- retry
82
- end
83
- riemann
84
- end
85
-
86
- # логика стартования плагинов
87
- def start_plugins(registered_plugins, riemann, logger, configatron)
88
- run_only = Array.new
89
- configatron.plugins.to_hash.keys.each { |key| run_only << key.to_s }
90
- registered_plugins.delete_if {|plugin| ! run_only.include? plugin.to_s.split('::').last.downcase }
91
-
92
- plugin_threads = registered_plugins.map do |plugin|
93
- Thread.new {
94
- plugin.new( configatron, logger, riemann ).run
95
- }
96
- end
97
-
98
- # plugin control
99
- Signal.trap 'TERM' do
100
- plugin_threads.each( &:kill )
101
- end
102
-
103
- plugin_threads.each( &:join )
104
- end
105
-
106
- def load_parent(configatron)
107
- configatron.to_hash[:plugins].each do |plugin, opts|
108
- next if opts.nil?
109
- next unless opts.kind_of? Hash
110
- create_class(plugin.capitalize, opts[:parent].capitalize) if opts.has_key? :parent
111
- end
112
- end
113
-
114
- # plugin load parent
115
- def create_class(new_class, parent_class)
116
- cmd = "class Riemann::Babbler::#{new_class} < Riemann::Babbler::#{parent_class}; end;"
117
- cmd += "Riemann::Babbler.registered_plugins << Riemann::Babbler::#{new_class}"
118
- eval(cmd)
119
- end
120
-
121
-