zabbix-monitor-modded 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NjcxNzEwZjM2Nzc4NmI5YTJjOWE2YTQ2ODIxMGJiOWZhMTYzNjA0NA==
5
+ data.tar.gz: !binary |-
6
+ N2UxNTQ2ZmU1NjY1ZjAxNzU2Y2U5ZGQyNjYwMDM0NWMyYTBiNGU2Nw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ Y2UyYWY4MzAxZjc3Y2ZhOWQ0NGQ5NWYxMTk1OTAzMGY4ODBjYWIyNmFmNDY2
10
+ NzI3NjViMTBhZmRlYzRmOWRlYjI0MTU5YjU2YTgzNThmZjNkMTA0NmE1ODYx
11
+ ODA4ZThmYzExNDY5ZWJiNmQzNDViODkxMTM4MjAzMTY4NDNlZjE=
12
+ data.tar.gz: !binary |-
13
+ ZjM3OGNhOGM5NjBiNjc1Yjk1YmYxZjUyMzhlZDJmMDkwNmIxOGZlNGIzMTI0
14
+ MDhhMzQzZWM2MTdiYzBkZmNhOTAzZTdhNGIxOGVjMDkwN2M5NmYxZTg2ZGM3
15
+ ODAwODFhYWJkYzhiMzMwZmU4YzkxYTdjY2U3MzE5ZjExNjBiNmY=
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .ruby-gemset
19
+ .ruby-version
20
+ log/*
21
+ /.rspec
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.0
7
+ - jruby-19mode
8
+ - ruby-head
9
+ - jruby-head
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ - rvm: jruby-head
14
+
15
+ addons:
16
+ code_climate:
17
+ repo_token: af39e5d1bbdd46699d027fd4eee89ed4cfa9d560eeafccf1293423651d0d6b0c
18
+
19
+ script: "bundle exec rake spec"
@@ -0,0 +1,5 @@
1
+ --readme README.md
2
+ --charset utf-8
3
+ --private
4
+ --protected
5
+ 'lib/**/*.rb' - '*.md'
@@ -0,0 +1,62 @@
1
+ # Zabbix Monitor Changelog
2
+
3
+ ##Changed to zabbix-monitor-modded and reversioned to 0.0.1
4
+
5
+ - Now gets hostname from config file
6
+ - Scheduler is now configurable
7
+ - Will not start unless a config file exists
8
+
9
+
10
+ ## v0.0.10 (2014-12-22)
11
+
12
+ - Require ActiveRecord 3.2 or higher
13
+
14
+ ## v0.0.9 (2014-12-22)
15
+
16
+ - Fixed some logging, docs and specs
17
+ - Require ActiveRecord explicit
18
+ - Added Capistrano tasks to stop and start the daemon to make it work with God.rb, removed after deploy:restart rule
19
+
20
+ ## v0.0.8 (2014-06-18)
21
+
22
+ - Made Yell log adapter configurable, defaults to :file
23
+
24
+ ## v0.0.7 (2014-06-18)
25
+
26
+ - Don't log while setting mode because the logger could still be uninitialized
27
+ - Don't create a symlinked log, depond on log rotate instead
28
+ - Added some logging to see if the monitor is running
29
+
30
+ ## v0.0.6 (2014-05-27)
31
+
32
+ - Moved pid files the the correct location
33
+
34
+ ## v0.0.5 (2014-05-27)
35
+
36
+ - Fixed permissions issue in v0.0.4
37
+
38
+ ## v0.0.4 (2014-05-27) (yanked)
39
+
40
+ - Added Capistrano 2 recipe
41
+
42
+ ## v0.0.3 (2014-05-27)
43
+
44
+ - Added codeclimate coverage
45
+ - Puts results to the STDOUT
46
+ - Removed YAML dependency from reader
47
+ - Use Dante to daemonize the monitoring tasks
48
+
49
+ ## v0.0.2 (2014-04-24)
50
+
51
+ - Added :file mode
52
+ - Write monitoring data to `tmp/zabbix-stats.yml`
53
+ - Read values with `$ zabbix_reader test`
54
+ - Added specs
55
+ - Added documentation
56
+ - Added services:
57
+ - Travis CI
58
+ - Rdoc
59
+
60
+ ## v0.0.1 (2014-04-17)
61
+
62
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in zabbix-agent-monitor.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Robert Jan de Gelder
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.
@@ -0,0 +1,126 @@
1
+ # Zabbix Monitor
2
+ [![Gem Version](https://badge.fury.io/rb/zabbix-monitor.png)][gemversion]
3
+ [![Build Status](https://secure.travis-ci.org/sping/zabbix-monitor.png?branch=master)][travis]
4
+ [![Code Climate](https://codeclimate.com/github/sping/zabbix-monitor.png)][codeclimate]
5
+ [![Coverage](https://codeclimate.com/github/sping/zabbix-monitor/coverage.png)][coverage]
6
+
7
+ [gemversion]: http://badge.fury.io/rb/zabbix-monitor
8
+ [travis]: http://travis-ci.org/sping/zabbix-monitor
9
+ [codeclimate]: https://codeclimate.com/github/sping/zabbix-monitor
10
+ [coverage]: https://codeclimate.com/github/sping/zabbix-monitor
11
+
12
+ Zabbix monitoring for Ruby apps. Works with pushing and polling: push data to the agent server with zabbix_sender or collect data with the Zabbix agent.
13
+
14
+ Here you can find [Documentation](http://rubydoc.info/github/sping/zabbix-monitor/master/frames)
15
+
16
+ ## Installation
17
+
18
+ Requires the Zabbix agent to be installed.
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'zabbix-monitor'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install zabbix-monitor
31
+
32
+ To include the rake tasks in your application, add the following line to your Rakefile (before `App::Application.load_tasks`):
33
+
34
+ require 'tasks/zabbix'
35
+
36
+ ## Usage
37
+
38
+ ### For Rails applications:
39
+
40
+ Place your Zabbix Monitoring configuration in an initializer:
41
+
42
+ ```ruby
43
+ require 'zabbix'
44
+
45
+ Zabbix.configure do |config|
46
+ config.config_file_path = '/etc/zabbix/zabbix_agentd.conf'
47
+ # optional, defaults to ./log/#{RACK_ENV}.log
48
+ # config.log_file_path = '/var/log/monitor.log'
49
+ config.rate = '1m'
50
+ config.mode = :push
51
+ config.rules = [
52
+ {
53
+ :command => 'Monitor.new.test',
54
+ :zabbix_key => 'zabbix.test'
55
+ }
56
+ ]
57
+ end
58
+ ```
59
+
60
+ Put the rate of the scheduler in rate.
61
+
62
+ Set the `config.mode` to one of the following options:
63
+
64
+ - `:push` uses the Zabbix agent to push the data to the Zabbix server
65
+ - `:file` writes the data to tmp/zabbix-stats.yml
66
+ - `:stdout` writes the data to the stdout
67
+
68
+ Put your monitoring rules in `config.rules`. Each rule contains a Ruby command to be executed by the Zabbix Monitor and the key as configured on the Zabbix Server.
69
+
70
+ Start running your monitoring jobs with:
71
+
72
+ $ rake zabbix:start
73
+
74
+ ### File mode
75
+
76
+ In `:file` mode, monitoring var can be read from the monitoring file using `zabbix_reader` command.
77
+ Create a script that's been executed by the Zabbix daemon:
78
+
79
+ ```bash
80
+ #! /bin/bash
81
+ cd /path/to/app/
82
+ echo $( RAILS_ENV=production bundle exec zabbix_reader $1 )
83
+ ```
84
+
85
+ To speed up the reading of variables, you can also use awk to look for variables. Create the following script instead:
86
+
87
+ ```bash
88
+ #! /bin/bash
89
+ cd /path/to/app/
90
+
91
+ if [ -f tmp/zabbix-stats.yml ]
92
+ then
93
+ echo $( awk -F: -v var=$1 '$0 ~ var {$1=""; print $0; exit}' tmp/zabbix-stats.yml )
94
+ else
95
+ echo Zabbix monitor file not found
96
+ fi
97
+ ```
98
+
99
+ ## Capistrano
100
+
101
+ Capistrano tasks are added in lib/tasks/zabbix.rb. Currently, only Capistrano 2 is supported. Add the following lines of code to your deploy.rb:
102
+
103
+ ```ruby
104
+ require 'zabbix/capistrano'
105
+
106
+ namespace :deploy do
107
+
108
+ # if you're running God.rb, it will be restarted automatically
109
+ after 'deploy:update_code', 'zabbix:stop'
110
+ # else
111
+ after 'deploy:update_code', 'zabbix:restart'
112
+
113
+ end
114
+ ```
115
+
116
+ ## Changelog
117
+
118
+ A detailed overview can be found in the [CHANGELOG](CHANGELOG.md).
119
+
120
+ ## Contributing
121
+
122
+ 1. Fork it
123
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
124
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
125
+ 4. Push to the branch (`git push origin my-new-feature`)
126
+ 5. Create new Pull Request
@@ -0,0 +1,11 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'yard'
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |task|
6
+ task.rspec_opts = ['--color', '--format', 'documentation']
7
+ end
8
+
9
+ YARD::Rake::YardocTask.new do |t|
10
+ t.options += ["--title", "Zabbix monitor Documentation"]
11
+ end
data/TODO.md ADDED
@@ -0,0 +1,5 @@
1
+ # Zabbix Monitor Todo
2
+
3
+ - Make Rufus Schedulere ActiveRecord independent
4
+ - Make schedule frequency configurable
5
+ - Capistrano integration / recipes
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'zabbix'
4
+
5
+ puts Zabbix::Reader.new.get_value ARGV[0]
@@ -0,0 +1,40 @@
1
+ require 'zabbix'
2
+ require 'dante'
3
+
4
+ namespace :zabbix do
5
+ desc 'Collect data for Zabbix'
6
+ task :run_once => :environment do
7
+ if Zabbix.run
8
+ Zabbix.logger.info "[Rake] executing #collect_once"
9
+ Zabbix::Monitor.new.collect_data
10
+ end
11
+ end
12
+
13
+ desc 'Collect data for Zabbix'
14
+ task :start => :environment do
15
+ if Zabbix.run
16
+ Zabbix.logger.info "[Rake] executing #start, setting up Rufus"
17
+ Dante::Runner.new('zabbix-monitor').execute(:daemonize => true, :pid_path => 'tmp/pids/zabbix-monitor.pid', :log_path => 'log/zabbix-monitor.log') do
18
+ Zabbix::Monitor.new.schedule
19
+ end
20
+ end
21
+ end
22
+
23
+ desc 'Stop collecting data for Zabbix'
24
+ task :stop => :environment do
25
+ if Zabbix.run
26
+ Zabbix.logger.info "[Rake] executing #stop, stopping daemon"
27
+ Dante::Runner.new('zabbix-monitor').execute(:kill => true, :pid_path => 'tmp/pids/zabbix-monitor.pid')
28
+ end
29
+ end
30
+
31
+ desc 'Restart collecting data for Zabbix'
32
+ task :restart => :environment do
33
+ if Zabbix.run
34
+ Zabbix.logger.info "[Rake] executing #stop, stopping daemon"
35
+ Dante::Runner.new('zabbix-monitor').execute(:daemonize => true, :restart => true, :pid_path => 'tmp/pids/zabbix-monitor.pid', :log_path => 'log/zabbix-monitor.log') do
36
+ Zabbix::Monitor.new.schedule
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,52 @@
1
+ require 'zabbix/config'
2
+ require 'zabbix/monitor'
3
+ require 'zabbix/reader'
4
+ require 'yell'
5
+
6
+ # Zabbix Monitor
7
+ module Zabbix
8
+
9
+ class FileNotFoundError < StandardError; end
10
+
11
+ class << self
12
+
13
+ # Call this method to modify defaults in your initializers.
14
+ #
15
+ # @example
16
+ # require 'zabbix'
17
+ #
18
+ # Zabbix.configure do |config|
19
+ # config.config_file_path = '/etc/zabbix/zabbix_agentd.conf'
20
+ # config.log_file_path = '/var/log/monitor.log' #optional
21
+ # config.rate = '1m'
22
+ # config.mode = :push
23
+ # config.rules = [
24
+ # {
25
+ # :command => 'Monitor.new.test',
26
+ # :zabbix_key => 'zabbix.test'
27
+ # }
28
+ # ]
29
+ # end
30
+ #
31
+ # @param [Hash] config variables
32
+ def configure
33
+ yield config
34
+ end
35
+
36
+ # @return [Zabbix::Config] creates a new or returns the existing the zabbix-monitor config
37
+ def config
38
+ @config ||= Config.new
39
+ end
40
+
41
+ def run
42
+ File.exist?(config.config_file_path)
43
+ end
44
+
45
+ # @return [Yell] creates a new or returns the +Yell+ logger instance
46
+ def logger
47
+ @logger ||= Yell.new do |l|
48
+ l.adapter self.config.log_adapter, :filename => self.config.log_file_path, :symlink => false
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,21 @@
1
+ require 'capistrano'
2
+
3
+ Capistrano::Configuration.instance.load do
4
+
5
+ namespace :zabbix do
6
+ desc 'Start Zabbix monitoring'
7
+ task :start, :roles => :web do
8
+ run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake zabbix:start"
9
+ end
10
+
11
+ desc 'Stop Zabbix monitoring'
12
+ task :stop, :roles => :web do
13
+ run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake zabbix:stop"
14
+ end
15
+
16
+ desc 'Restart Zabbix monitoring'
17
+ task :restart, :roles => :web do
18
+ run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake zabbix:restart"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,83 @@
1
+ module Zabbix
2
+
3
+ # The +Zabbix::Config+ object used for initializing zabbix-monitor
4
+ #
5
+ # @example
6
+ # Zabbix.configure do |config|
7
+ # config.config_file_path = '/etc/zabbix/zabbix_agentd.conf'
8
+ # config.log_file_path = '/var/log/monitor.log' #optional
9
+ # config.rate = '1m'
10
+ # config.mode = :push
11
+ # config.rules = [
12
+ # {
13
+ # :command => 'Monitor.new.test',
14
+ # :zabbix_key => 'zabbix.test'
15
+ # }
16
+ # ]
17
+ # end
18
+ #
19
+ class Config
20
+
21
+ # @return [String] the zabbix agentd config file location
22
+ attr_accessor :config_file_path
23
+
24
+ # @note
25
+ # (optional) Defaults to +./log/#{RACK_ENV}.log+
26
+ # @return [String] The zabbix-monitor log file location (optional)
27
+ attr_accessor :log_file_path
28
+
29
+ # @overload log_adapter
30
+ # @return [Symbol] The zabbix-monitor log adapter
31
+ # @overload log_adapter=(value)
32
+ # Sets the yell / zabbix-monitor log adapter
33
+ # See https://github.com/rudionrails/yell#usage for more information (optional)
34
+ #
35
+ # Options:
36
+ # :stdout logs to STDOUT
37
+ # :stderr logs to STDERR
38
+ # :file logs to a file
39
+ # :datefile logs to a timestamped file
40
+ # @param value [Symbol] the log_adapter
41
+ # @return [Symbol] the new log_adapter
42
+ attr_accessor :log_adapter
43
+
44
+ # @return [String] the zabbix hostname
45
+ attr_accessor :rate
46
+
47
+ # @return [Array<Symbol>] the set of rules to monitor
48
+ attr_accessor :rules
49
+
50
+ # @overload mode
51
+ # @return [Symbol] the mode zabbix-monitor uses to process the results of the rules
52
+ # @overload mode=(value)
53
+ # Sets the mode type, so zabbix-monitor knows how to process the results of the rules
54
+ #
55
+ # Options:
56
+ # :push uses the Zabbix agent to push the data to the Zabbix server
57
+ # :file writes the data to tmp/zabbix-stats.yml
58
+ # :stdout writes the data to the stdout
59
+ #
60
+ # @param value [Symbol] the mode
61
+ # @return [Symbol] the new mode
62
+ # @raise [StandardError] when a unsupported mode is specified
63
+ attr_accessor :mode
64
+
65
+ def mode= value
66
+ allowed_modes = [:push, :file, :stdout].freeze
67
+ if allowed_modes.include?(value)
68
+ @mode = value
69
+ else
70
+ raise "Unsupported mode: #{value}"
71
+ end
72
+ end
73
+
74
+ def log_file_path
75
+ @log_file_path || nil
76
+ end
77
+
78
+ def log_adapter
79
+ @log_adapter || :file
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,112 @@
1
+ require 'json'
2
+ require 'yaml'
3
+ require 'fileutils'
4
+ require 'rufus-scheduler'
5
+ require 'active_record'
6
+
7
+ module Zabbix
8
+
9
+ # Base class for processing and delivering the results to an endpoint
10
+ class Monitor
11
+
12
+ # Schedule the data collector
13
+ # @return [void]
14
+ def schedule
15
+ Rufus::Scheduler.new.tap do |scheduler|
16
+ scheduler.every config.rate do
17
+ scheduled_collect_data
18
+ end
19
+ end.join
20
+ end
21
+
22
+ # Loops through all rules and process the result
23
+ # @return [void]
24
+ def collect_data
25
+ Zabbix.logger.info '[Monitor] collecting data'
26
+ current_zabbix_rule = nil
27
+ config.rules.each do |rule|
28
+ current_zabbix_rule = rule
29
+ value = eval rule[:command]
30
+ process_data rule[:zabbix_key], value
31
+ end
32
+ rescue Exception => e
33
+ message = "#{current_zabbix_rule[:zabbix_key]} command: #{current_zabbix_rule[:command]} with message: #{e.message}"
34
+ Zabbix.logger.error "[Monitor] failed collecting data for rule: #{message}"
35
+ end
36
+
37
+ private
38
+
39
+ # @return [Zabbix::Config] the zabbix-monitor config
40
+ def config
41
+ Zabbix.config
42
+ end
43
+
44
+ # Process the result for a rule based on the mode specified in the config
45
+ #
46
+ # @param key [String] zabbix key
47
+ # @param value [String] the result from the rule's command
48
+ #
49
+ # @return [void]
50
+ def process_data key, value
51
+ case config.mode
52
+ when :push
53
+ to_zabbix key, value
54
+ when :file
55
+ to_file key, value
56
+ when :stdout
57
+ to_stdout key, value
58
+ end
59
+ end
60
+
61
+ # Use +zabbix_sender+ command to send each result to the Zabbix server
62
+ #
63
+ # @param key [String] zabbix key
64
+ # @param value [String] the result from the rule's command
65
+ #
66
+ # @return [void]
67
+ def to_zabbix key, value
68
+ result = `zabbix_sender -c #{config.config_file_path} -k #{key} -o #{value}`
69
+ case $?.to_i
70
+ when 0 # SUCCESS
71
+ Zabbix.logger.info "[Monitor] successfully sent rule: '#{key}' with value: '#{value}' to zabbix server"
72
+ else
73
+ Zabbix.logger.error "[Monitor] failed sending rule: '#{key}' with value: '#{value}' to zabbix server"
74
+ end
75
+ end
76
+
77
+ # Writes the result to a file
78
+ #
79
+ # @param key [String] zabbix key
80
+ # @param value [String] the result from the rule's command
81
+ #
82
+ # @return [void]
83
+ def to_file key, value
84
+ filename = 'tmp/zabbix-stats.yml'
85
+ Dir.mkdir 'tmp' unless Dir.exists? 'tmp'
86
+ if File.exists? filename
87
+ yml = YAML::load_file(filename)
88
+ else
89
+ yml = {'statistics' => {'created_at' => Time.now.to_i}}
90
+ end
91
+ yml['statistics'][key] = value
92
+
93
+ File.open(filename, 'w') { |file| file.write yml.to_yaml }
94
+ end
95
+
96
+ # Prints the result of the monitored rule to stdout
97
+ #
98
+ # @param key [String] zabbix key
99
+ # @param value [String] the result from the rule's command
100
+ #
101
+ # @return [void]
102
+ def to_stdout key, value
103
+ $stdout.puts "#{key}: #{value}"
104
+ end
105
+
106
+ def scheduled_collect_data
107
+ ActiveRecord::Base.connection_pool.with_connection do
108
+ collect_data
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,23 @@
1
+ require 'yaml'
2
+
3
+ module Zabbix
4
+
5
+ # The +Zabbix::Reader+ object used to get values from the monitor file
6
+ class Reader
7
+
8
+ def initialize
9
+ filename = 'tmp/zabbix-stats.yml'
10
+ raise FileNotFoundError, 'Monitoring file not found' if !File.exists?(filename)
11
+ @file = YAML.load_file(filename)
12
+ end
13
+
14
+ # Get a value from the Zabbix monitor file
15
+ #
16
+ # @param key [String] zabbix key
17
+ #
18
+ # @return [String] The monitoring value
19
+ def get_value key
20
+ @file['statistics'][key]
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Zabbix::Config do
4
+
5
+ let(:logger) { Zabbix.logger }
6
+ let(:config) { Zabbix::Config.new }
7
+
8
+ describe '#mode' do
9
+ it 'raises an unsupported mode for a invalid mode' do
10
+ expect { config.mode = :wrong }
11
+ .to raise_error(StandardError, 'Unsupported mode: wrong')
12
+ end
13
+ it 'raises an unsupported mode for a empty mode' do
14
+ expect { config.mode = '' }
15
+ .to raise_error(StandardError, 'Unsupported mode: ')
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,174 @@
1
+ require 'spec_helper'
2
+
3
+ describe Zabbix::Monitor do
4
+ let(:logger) { Zabbix.logger }
5
+ let(:monitor) { Zabbix::Monitor.new }
6
+ let(:config) { Zabbix::Config.new }
7
+
8
+ before :each do
9
+ allow(Zabbix).to receive(:config).and_return(config)
10
+ end
11
+
12
+ describe "#config" do
13
+ it 'returns the Zabbix monitor instance config' do
14
+ expect(Zabbix).to receive(:config)
15
+ monitor.send(:config)
16
+ end
17
+ end
18
+
19
+ describe '#scheduled_collect_data' do
20
+ it 'calls the #collect_data with an ActiveRecord connection from the pool' do
21
+ fake_connection = double
22
+ allow(fake_connection).to receive(:with_connection).and_yield
23
+ allow(ActiveRecord::Base).to receive(:connection_pool).and_return fake_connection
24
+ expect(monitor).to receive(:collect_data).once
25
+ monitor.send(:scheduled_collect_data)
26
+ end
27
+ end
28
+
29
+ describe '#schedule' do
30
+ let(:fake_rufus) { double }
31
+ let(:fake_collect_data) { double }
32
+
33
+ it 'schedule the data collector to run every minute' do
34
+ allow(fake_collect_data).to receive(:join)
35
+ allow(fake_rufus).to receive(:every).and_yield
36
+
37
+ expect_any_instance_of(Rufus::Scheduler).to receive(:tap).and_yield fake_rufus
38
+ expect(monitor).to receive(:scheduled_collect_data).once.and_return fake_collect_data
39
+ monitor.schedule
40
+ end
41
+ end
42
+
43
+ describe "#collect_data" do
44
+ # 'process data'
45
+ # 'raise exception invalid rule, invalid command, no command'
46
+ describe "one rule" do
47
+ before :each do
48
+ allow(config).to receive(:rules).and_return([
49
+ { :command => 'cmd', :zabbix_key => 'some.key' }
50
+ ])
51
+ end
52
+ it 'executes the command once and passes it to process' do
53
+ expect(monitor).to receive(:eval).once.and_return("result")
54
+ expect(monitor).to receive(:process_data).once.with('some.key', 'result')
55
+ monitor.collect_data
56
+ end
57
+ it 'catches the exception if command can not be excuted' do
58
+ exception = Exception.new("some error description")
59
+ expect(monitor).to receive(:eval).and_raise(exception)
60
+ expect(monitor).not_to receive(:process_data)
61
+ expect(logger).to receive(:error).with(/some.key command: cmd with message: some error description/)
62
+ monitor.collect_data
63
+ end
64
+ end
65
+ describe "two rules" do
66
+ before :each do
67
+ rules = [
68
+ { :command => 'cmd', :zabbix_key => 'some.key' },
69
+ { :command => 'cmd', :zabbix_key => 'another.key' }
70
+ ]
71
+ allow(config).to receive(:rules).and_return rules
72
+ end
73
+ it 'executes the command once and passes it to process' do
74
+ expect(monitor).to receive(:eval).twice.and_return("result")
75
+ expect(monitor).to receive(:process_data).once.with('some.key', 'result')
76
+ expect(monitor).to receive(:process_data).once.with('another.key', 'result')
77
+ monitor.collect_data
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "#process_data" do
83
+ it 'triggers the #to_zabbix for :push' do
84
+ config.mode = :push
85
+
86
+ expect(monitor).to receive(:to_zabbix).once.with(1, 2)
87
+ monitor.send(:process_data, 1, 2)
88
+ end
89
+ it 'triggers the #to_file for :file' do
90
+ config.mode = :file
91
+
92
+ expect(monitor).to receive(:to_file).once.with(1, 2)
93
+ monitor.send(:process_data, 1, 2)
94
+ end
95
+ it 'triggers the #stdout for :stdout' do
96
+ config.mode = :stdout
97
+
98
+ expect(monitor).to receive(:to_stdout).once.with(1, 2)
99
+ monitor.send(:process_data, 1, 2)
100
+ end
101
+ end
102
+
103
+ describe "#to_zabbix" do
104
+ before do
105
+ config.config_file_path = '/zabbix.conf'
106
+ config.host_name = 'servername'
107
+ end
108
+ it 'executes the zabbix_sender command with the correct arguments' do
109
+ expect(monitor).to receive(:'`').once.with('zabbix_sender -c /zabbix.conf -s "servername" -k key -o value')
110
+ allow(monitor).to receive(:puts)
111
+ monitor.send(:to_zabbix, 'key', 'value')
112
+ end
113
+ it 'outputs GREAT if the command is executed without errors' do
114
+ allow(monitor).to receive(:'`').and_return(`(exit 0)`)
115
+ expect(logger).to receive(:info).with(/successfully sent rule: 'key' with value: 'value' to zabbix server: 'servername'/)
116
+ monitor.send(:to_zabbix, 'key', 'value')
117
+ end
118
+ it 'outputs BUMMER if the command is executed with an error' do
119
+ allow(monitor).to receive(:'`').and_return(`(exit 1)`)
120
+ expect(logger).to receive(:error).with(/failed sending rule: 'key' with value: 'value' to zabbix server: 'servername'/)
121
+ monitor.send(:to_zabbix, 'key', 'value')
122
+ end
123
+ end
124
+
125
+ describe "#to_file" do
126
+ before :each do
127
+ allow(File).to receive(:exists?).and_return false
128
+ allow(File).to receive(:open).with('tmp/zabbix-stats.yml', 'w')
129
+ end
130
+ it 'creates the tmp folder if it does not exist' do
131
+ expect(Dir).to receive(:mkdir).once.with('tmp')
132
+ expect(Dir).to receive(:exists?).once.with('tmp').and_return(false)
133
+ monitor.send(:to_file, 'key', 'value')
134
+ end
135
+ it 'will not create the tmp folder if it already exists' do
136
+ expect(Dir).not_to receive(:mkdir).with('tmp')
137
+ expect(Dir).to receive(:exists?).once.with('tmp').and_return(true)
138
+ monitor.send(:to_file, 'key', 'value')
139
+ end
140
+ before :each do
141
+ allow(Dir).to receive(:exists?).and_return true
142
+ end
143
+ describe 'writeing and reading' do
144
+ it 'writes the result to "tmp/zabbix-stats.yml"' do
145
+ allow(File).to receive(:exists?).and_return false
146
+ file = double('file')
147
+ yml = {'statistics' => {'created_at' => Time.now.to_i, 'key' => 'value'}}
148
+
149
+ expect(File).to receive(:open).with('tmp/zabbix-stats.yml', 'w').and_yield(file)
150
+ expect(file).to receive(:write).with(yml.to_yaml)
151
+ monitor.send(:to_file, 'key', 'value')
152
+ end
153
+ it 'adds the key and value to the output file if it already exists' do
154
+ allow(File).to receive(:exists?).and_return true
155
+ file = double('file')
156
+ yml = {'statistics' => {'created_at' => Time.now.to_i, 'old_key' => 'old_value'}}
157
+
158
+ expect(YAML).to receive(:load_file).once.with('tmp/zabbix-stats.yml').and_return(yml)
159
+ expect(File).to receive(:open).with('tmp/zabbix-stats.yml', 'w').and_yield(file)
160
+
161
+ yml['statistics']['key'] = 'value'
162
+ expect(file).to receive(:write).with(yml.to_yaml)
163
+ monitor.send(:to_file, 'key', 'value')
164
+ end
165
+ end
166
+ end
167
+
168
+ describe "#to_stdout" do
169
+ it 'receives the key and value as a puts command' do
170
+ expect(STDOUT).to receive(:puts).with('key: the value')
171
+ monitor.send(:to_stdout, 'key', 'the value')
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe Zabbix::Reader do
4
+
5
+ before :each do
6
+ @filename = 'tmp/zabbix-stats.yml'
7
+ # File.open(@filename, 'w') { |file| file.write({'statistics' => {'test' => 'OK'}}.to_yaml) } unless File.exists?(@filename)
8
+ end
9
+
10
+ describe 'initialize' do
11
+ it 'raises an error when the file can\'t be found' do
12
+ expect(File).to receive(:exists?).with(@filename).and_return(false)
13
+ expect{ Zabbix::Reader.new }.to raise_error(Zabbix::FileNotFoundError, 'Monitoring file not found')
14
+ end
15
+
16
+ it 'reads the monitoring file from tmp' do
17
+ expect(File).to receive(:exists?).with(@filename).and_return(true)
18
+ expect(YAML).to receive(:load_file).with(@filename)
19
+ Zabbix::Reader.new
20
+ end
21
+ end
22
+
23
+ describe 'get_value' do
24
+ before :each do
25
+ expect(File).to receive(:exists?).and_return true
26
+ expect(YAML).to receive(:load_file).and_return({'statistics' => {'test' => 'OK'}})
27
+ end
28
+ let(:reader) { Zabbix::Reader.new }
29
+
30
+ it 'returns the requested value' do
31
+ expect(reader.get_value 'test').to eq('OK')
32
+ end
33
+
34
+ it 'returns nil when the key can\'t be found' do
35
+ expect(reader.get_value 'missing').to be_nil
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,20 @@
1
+ require 'pry'
2
+ require 'simplecov'
3
+ require "codeclimate-test-reporter"
4
+
5
+ CodeClimate::TestReporter.start
6
+ SimpleCov.start do
7
+ add_filter '/spec/'
8
+ end
9
+
10
+ require 'zabbix'
11
+
12
+ RSpec.configure do |config|
13
+ # configure yell logger's ENV and remove the logs files afterwards
14
+ ENV['YELL_ENV'] = 'test'
15
+
16
+ config.before :each do
17
+ log_path = File.expand_path("../log", File.dirname(__FILE__))
18
+ Dir[log_path + "/test*.log" ].each { |f| File.delete f }
19
+ end
20
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe Zabbix do
4
+ before :each do
5
+ # reset config
6
+ Zabbix.send(:config) { nil }
7
+ end
8
+
9
+ describe "#configure" do
10
+ describe "basic config vars and behaviour" do
11
+
12
+ it 'creates a new config for the Zabbix monitor instance' do
13
+ expect(Zabbix.config).to be_kind_of(Zabbix::Config)
14
+ end
15
+ it 'set the correct config values' do
16
+ Zabbix.configure do |config|
17
+ config.config_file_path = '/etc/zabbix/zabbix_agentd.conf'
18
+ config.host_name = 'servername'
19
+ config.mode = :push
20
+ end
21
+
22
+ expect(Zabbix.config.config_file_path).to eq '/etc/zabbix/zabbix_agentd.conf'
23
+ expect(Zabbix.config.log_file_path).to be_nil
24
+ expect(Zabbix.config.host_name).to eq 'servername'
25
+ expect(Zabbix.config.mode).to eq :push
26
+ pending 'should rules be initialized as an empty array?'
27
+ expect(Zabbix.config.rules.count).to eq 0
28
+ end
29
+ it 'returns the correct log_file_path if specified' do
30
+ Zabbix.configure do |config|
31
+ config.log_file_path = '/var/log/monitor.log'
32
+ end
33
+ expect(Zabbix.config.log_file_path).to eq '/var/log/monitor.log'
34
+ end
35
+ end
36
+
37
+ describe "rules" do
38
+ it 'has one rule' do
39
+ rule = { :command => 'a', :zabbix_key => 'a' }
40
+ Zabbix.configure do |config|
41
+ config.rules = [rule]
42
+ end
43
+ expect(Zabbix.config.rules).to eq [rule]
44
+ end
45
+ it 'has two rules' do
46
+ ruleA = { :command => 'a', :zabbix_key => 'a' }
47
+ ruleB = { :command => 'b', :zabbix_key => 'b' }
48
+ Zabbix.configure do |config|
49
+ config.rules = [ruleA, ruleB]
50
+ end
51
+ expect(Zabbix.config.rules).to eq [ruleA, ruleB]
52
+ end
53
+ it 'validates if the format of a rule from config is valid'
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'zabbix-monitor-modded'
7
+ spec.version = '0.0.3'
8
+ spec.authors = ['Robert Jan de Gelder', 'Manuel van Rijn', 'Stuart Speidel']
9
+ spec.email = ['r.degelder@sping.nl', 'm.vanrijn@sping.nl', '']
10
+ spec.description = 'Zabbix application monitoring'
11
+ spec.summary = 'Let the Zabbix agent read your application monitoring, modded to allow modifation of rate and not using a hardcoded server name'
12
+ spec.homepage = 'http://rubygems.org/gems/zabbix-monitor'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'rufus-scheduler', '~> 3.0'
21
+ spec.add_dependency 'yell', '~> 2.0'
22
+ spec.add_dependency 'dante', '~> 0.2.0'
23
+ spec.add_dependency 'activerecord', '~> 3.2'
24
+
25
+ spec.add_development_dependency 'rake','>=10.4.2'
26
+ spec.add_development_dependency 'bundler', '~> 1.3'
27
+ spec.add_development_dependency 'rspec', '~> 3.1'
28
+ spec.add_development_dependency 'pry','~>0.10.1'
29
+ spec.add_development_dependency 'pry-nav','~>0.2.4'
30
+ spec.add_development_dependency 'yard','~>0.8.7.6'
31
+ spec.add_development_dependency 'simplecov','~>0.10.0'
32
+ spec.add_development_dependency 'codeclimate-test-reporter','~>0.4.7'
33
+ end
metadata ADDED
@@ -0,0 +1,247 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zabbix-monitor-modded
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Robert Jan de Gelder
8
+ - Manuel van Rijn
9
+ - Stuart Speidel
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2015-08-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rufus-scheduler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: '3.0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: yell
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: '2.0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: '2.0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: dante
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ version: 0.2.0
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 0.2.0
57
+ - !ruby/object:Gem::Dependency
58
+ name: activerecord
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '3.2'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: '3.2'
71
+ - !ruby/object:Gem::Dependency
72
+ name: rake
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 10.4.2
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: 10.4.2
85
+ - !ruby/object:Gem::Dependency
86
+ name: bundler
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ version: '1.3'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: '1.3'
99
+ - !ruby/object:Gem::Dependency
100
+ name: rspec
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ~>
104
+ - !ruby/object:Gem::Version
105
+ version: '3.1'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ~>
111
+ - !ruby/object:Gem::Version
112
+ version: '3.1'
113
+ - !ruby/object:Gem::Dependency
114
+ name: pry
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ~>
118
+ - !ruby/object:Gem::Version
119
+ version: 0.10.1
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ~>
125
+ - !ruby/object:Gem::Version
126
+ version: 0.10.1
127
+ - !ruby/object:Gem::Dependency
128
+ name: pry-nav
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 0.2.4
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ~>
139
+ - !ruby/object:Gem::Version
140
+ version: 0.2.4
141
+ - !ruby/object:Gem::Dependency
142
+ name: yard
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ~>
146
+ - !ruby/object:Gem::Version
147
+ version: 0.8.7.6
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ~>
153
+ - !ruby/object:Gem::Version
154
+ version: 0.8.7.6
155
+ - !ruby/object:Gem::Dependency
156
+ name: simplecov
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ~>
160
+ - !ruby/object:Gem::Version
161
+ version: 0.10.0
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ~>
167
+ - !ruby/object:Gem::Version
168
+ version: 0.10.0
169
+ - !ruby/object:Gem::Dependency
170
+ name: codeclimate-test-reporter
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ~>
174
+ - !ruby/object:Gem::Version
175
+ version: 0.4.7
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ~>
181
+ - !ruby/object:Gem::Version
182
+ version: 0.4.7
183
+ description: Zabbix application monitoring
184
+ email:
185
+ - r.degelder@sping.nl
186
+ - m.vanrijn@sping.nl
187
+ - ''
188
+ executables:
189
+ - zabbix_reader
190
+ extensions: []
191
+ extra_rdoc_files: []
192
+ files:
193
+ - .gitignore
194
+ - .travis.yml
195
+ - .yardopts
196
+ - CHANGELOG.md
197
+ - Gemfile
198
+ - LICENSE.txt
199
+ - README.md
200
+ - Rakefile
201
+ - TODO.md
202
+ - bin/zabbix_reader
203
+ - lib/tasks/zabbix.rb
204
+ - lib/zabbix.rb
205
+ - lib/zabbix/capistrano.rb
206
+ - lib/zabbix/config.rb
207
+ - lib/zabbix/monitor.rb
208
+ - lib/zabbix/reader.rb
209
+ - log/.gitkeep
210
+ - spec/config_spec.rb
211
+ - spec/monitor_spec.rb
212
+ - spec/reader_spec.rb
213
+ - spec/spec_helper.rb
214
+ - spec/zabbix_spec.rb
215
+ - zabbix-monitor-modded.gemspec
216
+ homepage: http://rubygems.org/gems/zabbix-monitor
217
+ licenses:
218
+ - MIT
219
+ metadata: {}
220
+ post_install_message:
221
+ rdoc_options: []
222
+ require_paths:
223
+ - lib
224
+ required_ruby_version: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ! '>='
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ required_rubygems_version: !ruby/object:Gem::Requirement
230
+ requirements:
231
+ - - ! '>='
232
+ - !ruby/object:Gem::Version
233
+ version: '0'
234
+ requirements: []
235
+ rubyforge_project:
236
+ rubygems_version: 2.4.8
237
+ signing_key:
238
+ specification_version: 4
239
+ summary: Let the Zabbix agent read your application monitoring, modded to allow modifation
240
+ of rate and not using a hardcoded server name
241
+ test_files:
242
+ - spec/config_spec.rb
243
+ - spec/monitor_spec.rb
244
+ - spec/reader_spec.rb
245
+ - spec/spec_helper.rb
246
+ - spec/zabbix_spec.rb
247
+ has_rdoc: