zabbix-monitor 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.travis.yml +15 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +11 -0
- data/README.md +57 -5
- data/Rakefile +11 -1
- data/TODO.md +5 -0
- data/bin/zabbix_reader +5 -0
- data/lib/tasks/zabbix.rb +4 -9
- data/lib/zabbix.rb +30 -13
- data/lib/zabbix/config.rb +47 -8
- data/lib/zabbix/monitor.rb +60 -9
- data/lib/zabbix/reader.rb +23 -0
- data/spec/config_spec.rb +32 -0
- data/spec/monitor_spec.rb +154 -0
- data/spec/reader_spec.rb +39 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/zabbix_spec.rb +58 -0
- data/zabbix-monitor.gemspec +12 -6
- metadata +113 -9
- data/lib/zabbix/tasks.rb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d62efd8efb5101a7ee8573dc7703ff1808a99052
|
4
|
+
data.tar.gz: 654a0b6511265333477a3184cb6444f7b9b7d506
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a31b40d780051fc453afd55b0c2e4831e906b4f3739b27b2e4dc7a1e3f900417c9c33f44c0966b44ac5507410372fb0eac57cd401c127ea4fbd0662eef29cf14
|
7
|
+
data.tar.gz: 9bc5e2267cf60e84b7c4c3d26e4b6f817425be76952a4e6a99466f0603040c541bbe768a85e3b8e2f4068ac7c83af0f3389141b6bbd0d0e438d8759ca2711cb8
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,12 +1,23 @@
|
|
1
|
-
# Monitor
|
1
|
+
# Zabbix Monitor
|
2
|
+
[][gemversion]
|
3
|
+
[][travis]
|
4
|
+
[][codeclimate]
|
2
5
|
|
3
|
-
|
6
|
+
[gemversion]: http://badge.fury.io/rb/zabbix-monitor
|
7
|
+
[travis]: http://travis-ci.org/sping/zabbix-monitor
|
8
|
+
[codeclimate]: https://codeclimate.com/github/sping/zabbix-monitor
|
9
|
+
|
10
|
+
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.
|
11
|
+
|
12
|
+
Here you can find [Documentation](http://rubydoc.info/github/sping/zabbix-monitor/master/frames)
|
4
13
|
|
5
14
|
## Installation
|
6
15
|
|
16
|
+
Requires the Zabbix agent to be installed.
|
17
|
+
|
7
18
|
Add this line to your application's Gemfile:
|
8
19
|
|
9
|
-
gem 'zabbix-
|
20
|
+
gem 'zabbix-monitor'
|
10
21
|
|
11
22
|
And then execute:
|
12
23
|
|
@@ -14,11 +25,52 @@ And then execute:
|
|
14
25
|
|
15
26
|
Or install it yourself as:
|
16
27
|
|
17
|
-
$ gem install zabbix-
|
28
|
+
$ gem install zabbix-monitor
|
29
|
+
|
30
|
+
To include the rake tasks in your application, add the following line to your Rakefile (before `App::Application.load_tasks`):
|
31
|
+
|
32
|
+
require 'zabbix/tasks'
|
18
33
|
|
19
34
|
## Usage
|
20
35
|
|
21
|
-
|
36
|
+
### For Rails applications:
|
37
|
+
|
38
|
+
Place your Zabbix Monitoring configuration in an initializer:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
Zabbix.configure do |config|
|
42
|
+
config.config_file_path = '/etc/zabbix/zabbix_agentd.conf'
|
43
|
+
# optional, defaults to ./log/#{RACK_ENV}.log
|
44
|
+
# config.log_file_path = '/var/log/monitor.log'
|
45
|
+
config.host_name = 'servername'
|
46
|
+
config.mode = :push
|
47
|
+
config.rules = [
|
48
|
+
{
|
49
|
+
:command => 'Monitor.new.test',
|
50
|
+
:zabbix_key => 'zabbix.test'
|
51
|
+
}
|
52
|
+
]
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Put the host name as configured in your Zabbix server config in `config.host_name`.
|
57
|
+
|
58
|
+
Set the `config.mode` to one of the following options:
|
59
|
+
|
60
|
+
- `:push` uses the Zabbix agent to push the data to the Zabbix server
|
61
|
+
- `:file` writes the data to tmp/zabbix/monitor
|
62
|
+
- `:stdout` writes the data to the stdout
|
63
|
+
|
64
|
+
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.
|
65
|
+
|
66
|
+
Start running your monitoring jobs with:
|
67
|
+
|
68
|
+
$ rake zabbix:collect_data
|
69
|
+
|
70
|
+
|
71
|
+
## Changelog
|
72
|
+
|
73
|
+
A detailed overview can be found in the [CHANGELOG](CHANGELOG.md).
|
22
74
|
|
23
75
|
## Contributing
|
24
76
|
|
data/Rakefile
CHANGED
@@ -1 +1,11 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
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
data/bin/zabbix_reader
ADDED
data/lib/tasks/zabbix.rb
CHANGED
@@ -1,20 +1,15 @@
|
|
1
1
|
require 'zabbix'
|
2
|
-
require 'rufus-scheduler'
|
3
2
|
|
4
3
|
namespace :zabbix do
|
5
4
|
desc 'Collect data for Zabbix'
|
6
5
|
task :collect_once => :environment do
|
6
|
+
Zabbix.logger.info "[Rake] executing #collect_once"
|
7
7
|
Zabbix::Monitor.new.collect_data
|
8
8
|
end
|
9
9
|
|
10
10
|
desc 'Collect data for Zabbix every minute'
|
11
11
|
task :collect_data => :environment do
|
12
|
-
|
13
|
-
|
14
|
-
ActiveRecord::Base.connection_pool.with_connection do
|
15
|
-
Zabbix::Monitor.new.collect_data
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end.join
|
12
|
+
Zabbix.logger.info "[Rake] executing #collect_data, setting up Rufus"
|
13
|
+
Zabbix::Monitor.new.schedule
|
19
14
|
end
|
20
|
-
end
|
15
|
+
end
|
data/lib/zabbix.rb
CHANGED
@@ -1,31 +1,48 @@
|
|
1
1
|
require 'zabbix/config'
|
2
2
|
require 'zabbix/monitor'
|
3
|
+
require 'zabbix/reader'
|
4
|
+
require 'yell'
|
3
5
|
|
6
|
+
# Zabbix Monitor
|
4
7
|
module Zabbix
|
5
8
|
|
9
|
+
class FileNotFoundError < StandardError; end
|
10
|
+
|
6
11
|
class << self
|
7
12
|
|
8
13
|
# Call this method to modify defaults in your initializers.
|
9
14
|
#
|
10
|
-
# example
|
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.host_name = 'servername'
|
22
|
+
# config.mode = :push
|
23
|
+
# config.rules = [
|
24
|
+
# {
|
25
|
+
# :command => 'Monitor.new.test',
|
26
|
+
# :zabbix_key => 'zabbix.test'
|
27
|
+
# }
|
28
|
+
# ]
|
29
|
+
# end
|
11
30
|
#
|
12
|
-
#
|
13
|
-
# config.config_file_path = '/etc/zabbix/zabbix_agentd.conf'
|
14
|
-
# config.host_name = 'servername'
|
15
|
-
# config.mode = :push
|
16
|
-
# config.rules = [
|
17
|
-
# {
|
18
|
-
# :command => 'Monitor.new.test',
|
19
|
-
# :zabbix_key => 'zabbix.test'
|
20
|
-
# }
|
21
|
-
# ]
|
22
|
-
# end
|
31
|
+
# @param [Hash] config variables
|
23
32
|
def configure
|
24
33
|
yield config
|
25
34
|
end
|
26
35
|
|
36
|
+
# @return [Zabbix::Config] creates a new or returns the existing the zabbix-monitor config
|
27
37
|
def config
|
28
38
|
@config ||= Config.new
|
29
39
|
end
|
40
|
+
|
41
|
+
# @return [Yell] creates a new or returns the +Yell+ logger instance
|
42
|
+
def logger
|
43
|
+
@logger ||= Yell.new do |l|
|
44
|
+
l.adapter :datefile, :filename => self.config.log_file_path, :symlink => true
|
45
|
+
end
|
46
|
+
end
|
30
47
|
end
|
31
|
-
end
|
48
|
+
end
|
data/lib/zabbix/config.rb
CHANGED
@@ -1,23 +1,62 @@
|
|
1
1
|
module Zabbix
|
2
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.host_name = 'servername'
|
10
|
+
# config.mode = :push
|
11
|
+
# config.rules = [
|
12
|
+
# {
|
13
|
+
# :command => 'Monitor.new.test',
|
14
|
+
# :zabbix_key => 'zabbix.test'
|
15
|
+
# }
|
16
|
+
# ]
|
17
|
+
# end
|
18
|
+
#
|
3
19
|
class Config
|
4
20
|
|
5
|
-
|
6
|
-
|
7
|
-
#
|
21
|
+
# @return [String] the zabbix agentd config file location
|
22
|
+
attr_accessor :config_file_path
|
23
|
+
# @note
|
24
|
+
# (optional) Defaults to +./log/#{RACK_ENV}.log+
|
25
|
+
# @return [String] The zabbix-monitor log file location (optional)
|
26
|
+
attr_accessor :log_file_path
|
27
|
+
# @return [String] the zabbix hostname
|
28
|
+
attr_accessor :host_name
|
29
|
+
# @return [Array<Symbol>] the set of rules to monitor
|
30
|
+
attr_accessor :rules
|
31
|
+
# @overload mode
|
32
|
+
# @return [Symbol] the mode zabbix-monitor uses to process the results of the rules
|
33
|
+
# @overload mode=(value)
|
34
|
+
# Sets the mode type, so zabbix-monitor knows how to process the results of the rules
|
8
35
|
#
|
9
|
-
#
|
36
|
+
# Options:
|
37
|
+
# :push uses the Zabbix agent to push the data to the Zabbix server
|
38
|
+
# :file writes the data to tmp/zabbix-stats.yml
|
39
|
+
# :stdout writes the data to the stdout
|
10
40
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
41
|
+
# @param value [Symbol] the mode
|
42
|
+
# @return [Symbol] the new mode
|
43
|
+
# @raise [StandardError] when a unsupported mode is specified
|
44
|
+
attr_accessor :mode
|
45
|
+
|
14
46
|
def mode= value
|
15
47
|
allowed_modes = [:push, :file, :stdout].freeze
|
16
48
|
if allowed_modes.include?(value)
|
49
|
+
Zabbix.logger.info "[Config] setting mode to '#{value}'"
|
17
50
|
@mode = value
|
18
51
|
else
|
52
|
+
Zabbix.logger.error "[Config] failed setting mode to '#{value}'"
|
19
53
|
raise "Unsupported mode: #{value}"
|
20
54
|
end
|
21
55
|
end
|
56
|
+
|
57
|
+
def log_file_path
|
58
|
+
@log_file_path || nil
|
59
|
+
end
|
60
|
+
|
22
61
|
end
|
23
|
-
end
|
62
|
+
end
|
data/lib/zabbix/monitor.rb
CHANGED
@@ -1,25 +1,52 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'rufus-scheduler'
|
2
5
|
|
3
6
|
module Zabbix
|
4
7
|
|
8
|
+
# Base class for processing and delivering the results to an endpoint
|
5
9
|
class Monitor
|
6
10
|
|
11
|
+
# Schedule the data collector
|
12
|
+
# @return [void]
|
13
|
+
def schedule
|
14
|
+
Rufus::Scheduler.new.tap do |scheduler|
|
15
|
+
scheduler.every '1m' do
|
16
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
17
|
+
collect_data
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end.join
|
21
|
+
end
|
22
|
+
|
23
|
+
# Loops through all rules and process the result
|
24
|
+
# @return [void]
|
7
25
|
def collect_data
|
26
|
+
current_zabbix_rule = nil
|
8
27
|
config.rules.each do |rule|
|
28
|
+
current_zabbix_rule = rule
|
9
29
|
value = eval rule[:command]
|
10
30
|
process_data rule[:zabbix_key], value
|
11
31
|
end
|
12
32
|
rescue Exception => e
|
13
|
-
|
14
|
-
|
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}"
|
15
35
|
end
|
16
36
|
|
17
37
|
private
|
18
38
|
|
39
|
+
# @return [Zabbix::Config] the zabbix-monitor config
|
19
40
|
def config
|
20
41
|
Zabbix.config
|
21
42
|
end
|
22
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]
|
23
50
|
def process_data key, value
|
24
51
|
case config.mode
|
25
52
|
when :push
|
@@ -28,28 +55,52 @@ module Zabbix
|
|
28
55
|
to_file key, value
|
29
56
|
when :stdout
|
30
57
|
to_stdout key, value
|
31
|
-
else
|
32
|
-
to_stdout key, value
|
33
58
|
end
|
34
59
|
end
|
35
60
|
|
36
|
-
# Use zabbix_sender command to send each result to the Zabbix server
|
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]
|
37
67
|
def to_zabbix key, value
|
38
68
|
result = `zabbix_sender -c #{config.config_file_path} -s "#{config.host_name}" -k #{key} -o #{value}`
|
39
69
|
case $?.to_i
|
40
70
|
when 0 # SUCCESS
|
41
|
-
|
71
|
+
Zabbix.logger.info "[Monitor] successfully sended rule: '#{key}' to zabbix server: '#{config.host_name}'"
|
42
72
|
else
|
43
|
-
|
73
|
+
Zabbix.logger.error "[Monitor] failed sending rule: '#{key}' with value: '#{value}' to zabbix server: '#{config.host_name}'"
|
44
74
|
end
|
45
75
|
end
|
46
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]
|
47
83
|
def to_file key, value
|
48
|
-
|
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 }
|
49
94
|
end
|
50
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]
|
51
102
|
def to_stdout key, value
|
52
103
|
puts "#{key}: #{value}"
|
53
104
|
end
|
54
105
|
end
|
55
|
-
end
|
106
|
+
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
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
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 'allows setting mode to push' do
|
10
|
+
expect(logger).to receive(:info).with(/setting mode to 'push'/)
|
11
|
+
config.mode = :push
|
12
|
+
end
|
13
|
+
it 'allows setting mode to file' do
|
14
|
+
expect(logger).to receive(:info).with(/setting mode to 'file'/)
|
15
|
+
config.mode = :file
|
16
|
+
end
|
17
|
+
it 'allows setting mode to stdout' do
|
18
|
+
expect(logger).to receive(:info).with(/setting mode to 'stdout'/)
|
19
|
+
config.mode = :stdout
|
20
|
+
end
|
21
|
+
it 'raises an unsupported mode for a invalid mode' do
|
22
|
+
expect(logger).to receive(:error).with(/failed setting mode to 'wrong'/)
|
23
|
+
expect { config.mode = :wrong }
|
24
|
+
.to raise_error(StandardError, 'Unsupported mode: wrong')
|
25
|
+
end
|
26
|
+
it 'raises an unsupported mode for a empty mode' do
|
27
|
+
expect(logger).to receive(:error).with(/failed setting mode to ''/)
|
28
|
+
expect { config.mode = '' }
|
29
|
+
.to raise_error(StandardError, 'Unsupported mode: ')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,154 @@
|
|
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
|
+
Zabbix.stub(:config) { config }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#config" do
|
13
|
+
it 'returns the Zabbix monitor instance config' do
|
14
|
+
monitor.send(:config).should eq config
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#schedule' do
|
19
|
+
it 'schedule the data collector to run every minute' do
|
20
|
+
pending 'add scheduler test magic here'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#collect_data" do
|
25
|
+
# 'process data'
|
26
|
+
# 'raise exception invalid rule, invalid command, no command'
|
27
|
+
describe "one rule" do
|
28
|
+
before :each do
|
29
|
+
config.stub(:rules) {[
|
30
|
+
{ :command => 'cmd', :zabbix_key => 'some.key' }
|
31
|
+
]}
|
32
|
+
end
|
33
|
+
it 'executes the command once and passes it to process' do
|
34
|
+
expect(monitor).to receive(:eval).once.and_return("result")
|
35
|
+
expect(monitor).to receive(:process_data).once.with('some.key', 'result')
|
36
|
+
monitor.collect_data
|
37
|
+
end
|
38
|
+
it 'catches the exception if command can not be excuted' do
|
39
|
+
exception = Exception.new("some error description")
|
40
|
+
expect(monitor).to receive(:eval).and_raise(exception)
|
41
|
+
expect(monitor).not_to receive(:process_data)
|
42
|
+
expect(logger).to receive(:error).with(/some.key command: cmd with message: some error description/)
|
43
|
+
monitor.collect_data
|
44
|
+
end
|
45
|
+
end
|
46
|
+
describe "two rules" do
|
47
|
+
before :each do
|
48
|
+
config.stub(:rules) {[
|
49
|
+
{ :command => 'cmd', :zabbix_key => 'some.key' },
|
50
|
+
{ :command => 'cmd', :zabbix_key => 'another.key' }
|
51
|
+
]}
|
52
|
+
end
|
53
|
+
it 'executes the command once and passes it to process' do
|
54
|
+
expect(monitor).to receive(:eval).twice.and_return("result")
|
55
|
+
expect(monitor).to receive(:process_data).once.with('some.key', 'result')
|
56
|
+
expect(monitor).to receive(:process_data).once.with('another.key', 'result')
|
57
|
+
monitor.collect_data
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#process_data" do
|
63
|
+
it 'triggers the #to_zabbix for :push' do
|
64
|
+
config.mode = :push
|
65
|
+
|
66
|
+
expect(monitor).to receive(:to_zabbix).once.with(1, 2)
|
67
|
+
monitor.send(:process_data, 1, 2)
|
68
|
+
end
|
69
|
+
it 'triggers the #to_file for :file' do
|
70
|
+
config.mode = :file
|
71
|
+
|
72
|
+
expect(monitor).to receive(:to_file).once.with(1, 2)
|
73
|
+
monitor.send(:process_data, 1, 2)
|
74
|
+
end
|
75
|
+
it 'triggers the #stdout for :stdout' do
|
76
|
+
config.mode = :stdout
|
77
|
+
|
78
|
+
expect(monitor).to receive(:to_stdout).once.with(1, 2)
|
79
|
+
monitor.send(:process_data, 1, 2)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#to_zabbix" do
|
84
|
+
before do
|
85
|
+
config.config_file_path = '/zabbix.conf'
|
86
|
+
config.host_name = 'servername'
|
87
|
+
end
|
88
|
+
it 'executes the zabbix_sender command with the correct arguments' do
|
89
|
+
expect(monitor).to receive(:'`').once.with('zabbix_sender -c /zabbix.conf -s "servername" -k key -o value')
|
90
|
+
monitor.stub(:puts) {}
|
91
|
+
monitor.send(:to_zabbix, 'key', 'value')
|
92
|
+
end
|
93
|
+
it 'outputs GREAT if the command is executed without errors' do
|
94
|
+
monitor.stub(:'`') { `(exit 0)` }
|
95
|
+
expect(logger).to receive(:info).with(/successfully sended rule: 'key' to zabbix server: 'servername'/)
|
96
|
+
monitor.send(:to_zabbix, 'key', 'value')
|
97
|
+
end
|
98
|
+
it 'outputs BUMMER if the command is executed with an error' do
|
99
|
+
monitor.stub(:'`') { `(exit -1)` }
|
100
|
+
expect(logger).to receive(:error).with(/failed sending rule: 'key' with value: 'value' to zabbix server: 'servername'/)
|
101
|
+
monitor.send(:to_zabbix, 'key', 'value')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "#to_file" do
|
106
|
+
before :each do
|
107
|
+
File.stub(:exists?) { false }
|
108
|
+
File.stub(:open).with('tmp/zabbix-stats.yml', 'w')
|
109
|
+
end
|
110
|
+
it 'creates the tmp folder if it does not exist' do
|
111
|
+
expect(Dir).to receive(:mkdir).once.with('tmp')
|
112
|
+
expect(Dir).to receive(:exists?).once.with('tmp').and_return(false)
|
113
|
+
monitor.send(:to_file, 'key', 'value')
|
114
|
+
end
|
115
|
+
it 'will not create the tmp folder if it already exists' do
|
116
|
+
expect(Dir).not_to receive(:mkdir).with('tmp')
|
117
|
+
expect(Dir).to receive(:exists?).once.with('tmp').and_return(true)
|
118
|
+
monitor.send(:to_file, 'key', 'value')
|
119
|
+
end
|
120
|
+
before :each do
|
121
|
+
Dir.stub(:exists?) { true }
|
122
|
+
end
|
123
|
+
describe 'writeing and reading' do
|
124
|
+
it 'writes the result to "tmp/zabbix-stats.yml"' do
|
125
|
+
File.stub(:exists?) { false }
|
126
|
+
file = double('file')
|
127
|
+
yml = {'statistics' => {'created_at' => Time.now.to_i, 'key' => 'value'}}
|
128
|
+
|
129
|
+
expect(File).to receive(:open).with('tmp/zabbix-stats.yml', 'w').and_yield(file)
|
130
|
+
expect(file).to receive(:write).with(yml.to_yaml)
|
131
|
+
monitor.send(:to_file, 'key', 'value')
|
132
|
+
end
|
133
|
+
it 'adds the key and value to the output file if it already exists' do
|
134
|
+
File.stub(:exists?) { true }
|
135
|
+
file = double('file')
|
136
|
+
yml = {'statistics' => {'created_at' => Time.now.to_i, 'old_key' => 'old_value'}}
|
137
|
+
|
138
|
+
expect(YAML).to receive(:load_file).once.with('tmp/zabbix-stats.yml').and_return(yml)
|
139
|
+
expect(File).to receive(:open).with('tmp/zabbix-stats.yml', 'w').and_yield(file)
|
140
|
+
|
141
|
+
yml['statistics']['key'] = 'value'
|
142
|
+
expect(file).to receive(:write).with(yml.to_yaml)
|
143
|
+
monitor.send(:to_file, 'key', 'value')
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#to_stdout" do
|
149
|
+
it 'receives the key and value as a puts command' do
|
150
|
+
expect(monitor).to receive(:puts).with('key: the value')
|
151
|
+
monitor.send(:to_stdout, 'key', 'the value')
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/spec/reader_spec.rb
ADDED
@@ -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
|
+
File.stub(:exists?) { true }
|
26
|
+
YAML.stub(:load_file) { {'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
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'simplecov'
|
3
|
+
|
4
|
+
SimpleCov.start do
|
5
|
+
add_filter '/spec/'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'zabbix'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
# configure yell logger's ENV and remove the logs files afterwards
|
12
|
+
ENV['YELL_ENV'] = 'test'
|
13
|
+
|
14
|
+
config.before :each do
|
15
|
+
log_path = File.expand_path("../log", File.dirname(__FILE__))
|
16
|
+
Dir[log_path + "/test*.log" ].each { |f| File.delete f }
|
17
|
+
end
|
18
|
+
end
|
data/spec/zabbix_spec.rb
ADDED
@@ -0,0 +1,58 @@
|
|
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
|
+
Zabbix.config.should 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
|
+
Zabbix.config.config_file_path.should eq '/etc/zabbix/zabbix_agentd.conf'
|
23
|
+
Zabbix.config.log_file_path.should be_nil
|
24
|
+
Zabbix.config.host_name.should eq 'servername'
|
25
|
+
Zabbix.config.mode.should eq :push
|
26
|
+
pending 'should rules be initialized as an empty array?'
|
27
|
+
Zabbix.config.rules.count.should 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
|
+
Zabbix.config.log_file_path.should 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
|
+
Zabbix.config.rules.should 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
|
+
Zabbix.config.rules.should eq [ruleA, ruleB]
|
52
|
+
end
|
53
|
+
it 'validates if the format of a rule from config is valid' do
|
54
|
+
pending 'todo'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/zabbix-monitor.gemspec
CHANGED
@@ -4,21 +4,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'zabbix-monitor'
|
7
|
-
spec.version = '0.0.
|
8
|
-
spec.authors = ['Robert Jan de Gelder']
|
9
|
-
spec.email = ['r.degelder@sping.nl']
|
7
|
+
spec.version = '0.0.2'
|
8
|
+
spec.authors = ['Robert Jan de Gelder', 'Manuel van Rijn']
|
9
|
+
spec.email = ['r.degelder@sping.nl', 'm.vanrijn@sping.nl']
|
10
10
|
spec.description = 'Zabbix application monitoring'
|
11
11
|
spec.summary = 'Let the Zabbix agent read your application monitoring'
|
12
12
|
spec.homepage = 'http://rubygems.org/gems/zabbix-monitor'
|
13
13
|
spec.license = 'MIT'
|
14
14
|
|
15
15
|
spec.files = `git ls-files`.split($/)
|
16
|
-
|
17
|
-
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
|
-
spec.add_dependency 'rufus-scheduler'
|
20
|
+
spec.add_dependency 'rufus-scheduler', '~> 3.0'
|
21
|
+
spec.add_dependency 'yell', '~> 2.0'
|
21
22
|
|
22
23
|
spec.add_development_dependency 'rake'
|
23
24
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
25
|
+
spec.add_development_dependency 'rspec', '~> 2.14'
|
26
|
+
spec.add_development_dependency 'pry'
|
27
|
+
spec.add_development_dependency 'pry-nav'
|
28
|
+
spec.add_development_dependency 'yard'
|
29
|
+
spec.add_development_dependency 'simplecov'
|
24
30
|
end
|
metadata
CHANGED
@@ -1,29 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zabbix-monitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Jan de Gelder
|
8
|
+
- Manuel van Rijn
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
12
|
+
date: 2014-04-24 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rufus-scheduler
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- -
|
18
|
+
- - ~>
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
+
version: '3.0'
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- -
|
25
|
+
- - ~>
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
+
version: '3.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: yell
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.0'
|
27
42
|
- !ruby/object:Gem::Dependency
|
28
43
|
name: rake
|
29
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,23 +67,106 @@ dependencies:
|
|
52
67
|
- - ~>
|
53
68
|
- !ruby/object:Gem::Version
|
54
69
|
version: '1.3'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.14'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.14'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: pry
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: pry-nav
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: yard
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: simplecov
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
55
140
|
description: Zabbix application monitoring
|
56
141
|
email:
|
57
142
|
- r.degelder@sping.nl
|
58
|
-
|
143
|
+
- m.vanrijn@sping.nl
|
144
|
+
executables:
|
145
|
+
- zabbix_reader
|
59
146
|
extensions: []
|
60
147
|
extra_rdoc_files: []
|
61
148
|
files:
|
62
149
|
- .gitignore
|
150
|
+
- .travis.yml
|
151
|
+
- .yardopts
|
152
|
+
- CHANGELOG.md
|
63
153
|
- Gemfile
|
64
154
|
- LICENSE.txt
|
65
155
|
- README.md
|
66
156
|
- Rakefile
|
157
|
+
- TODO.md
|
158
|
+
- bin/zabbix_reader
|
67
159
|
- lib/tasks/zabbix.rb
|
68
160
|
- lib/zabbix.rb
|
69
161
|
- lib/zabbix/config.rb
|
70
162
|
- lib/zabbix/monitor.rb
|
71
|
-
- lib/zabbix/
|
163
|
+
- lib/zabbix/reader.rb
|
164
|
+
- log/.gitkeep
|
165
|
+
- spec/config_spec.rb
|
166
|
+
- spec/monitor_spec.rb
|
167
|
+
- spec/reader_spec.rb
|
168
|
+
- spec/spec_helper.rb
|
169
|
+
- spec/zabbix_spec.rb
|
72
170
|
- zabbix-monitor.gemspec
|
73
171
|
homepage: http://rubygems.org/gems/zabbix-monitor
|
74
172
|
licenses:
|
@@ -94,4 +192,10 @@ rubygems_version: 2.1.11
|
|
94
192
|
signing_key:
|
95
193
|
specification_version: 4
|
96
194
|
summary: Let the Zabbix agent read your application monitoring
|
97
|
-
test_files:
|
195
|
+
test_files:
|
196
|
+
- spec/config_spec.rb
|
197
|
+
- spec/monitor_spec.rb
|
198
|
+
- spec/reader_spec.rb
|
199
|
+
- spec/spec_helper.rb
|
200
|
+
- spec/zabbix_spec.rb
|
201
|
+
has_rdoc:
|
data/lib/zabbix/tasks.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'tasks/zabbix'
|