zabbix-ruby-client 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +6 -9
  4. data/lib/zabbix-ruby-client/data.rb +6 -4
  5. data/lib/zabbix-ruby-client/plugin_base.rb +41 -0
  6. data/lib/zabbix-ruby-client/plugins/apache.rb +1 -1
  7. data/lib/zabbix-ruby-client/plugins/apt.rb +32 -10
  8. data/lib/zabbix-ruby-client/plugins/cpu.rb +32 -23
  9. data/lib/zabbix-ruby-client/plugins/disk.rb +52 -33
  10. data/lib/zabbix-ruby-client/plugins/load.rb +22 -15
  11. data/lib/zabbix-ruby-client/plugins/memory.rb +48 -26
  12. data/lib/zabbix-ruby-client/plugins/network.rb +26 -17
  13. data/lib/zabbix-ruby-client/plugins/nginx.rb +1 -0
  14. data/lib/zabbix-ruby-client/plugins/postgres.rb +64 -0
  15. data/lib/zabbix-ruby-client/version.rb +1 -1
  16. data/spec/files/plugins/sample_buggy.rb +11 -0
  17. data/spec/files/plugins/sample_discover.rb +12 -0
  18. data/spec/files/system/apache_status +7 -6
  19. data/spec/files/system/apt-check +1 -0
  20. data/spec/files/system/df +1 -0
  21. data/spec/files/system/diskstats +1 -0
  22. data/spec/files/system/loadavg +1 -0
  23. data/spec/files/system/meminfo +46 -0
  24. data/spec/files/system/net_dev +1 -0
  25. data/spec/files/system/proc_cpu +1 -0
  26. data/spec/files/task_discovery.yml +3 -0
  27. data/spec/lib/cli_spec.rb +44 -6
  28. data/spec/lib/data_spec.rb +58 -1
  29. data/spec/lib/plugin_base_spec.rb +54 -0
  30. data/spec/lib/plugins/apache_spec.rb +78 -5
  31. data/spec/lib/plugins/apt_spec.rb +45 -0
  32. data/spec/lib/plugins/cpu_spec.rb +51 -1
  33. data/spec/lib/plugins/disk_spec.rb +77 -1
  34. data/spec/lib/plugins/load_spec.rb +41 -0
  35. data/spec/lib/plugins/memory_spec.rb +83 -2
  36. data/spec/lib/plugins/network_spec.rb +60 -1
  37. data/spec/lib/plugins_spec.rb +3 -1
  38. data/templates/client/postgres.yml +3 -0
  39. data/zabbix-ruby-client.gemspec +1 -0
  40. data/zabbix-templates/postgres_tpl.xml +833 -0
  41. metadata +79 -15
  42. checksums.yaml +0 -7
@@ -1,33 +1,31 @@
1
1
  require "zabbix-ruby-client/logger"
2
+ require "zabbix-ruby-client/plugin_base"
2
3
 
3
4
  module ZabbixRubyClient
4
5
  module Plugins
5
6
  module Network
6
7
  extend self
8
+ extend ZabbixRubyClient::PluginBase
7
9
 
8
10
  def collect(*args)
9
11
  host = args[0]
10
12
  interface = args[1]
11
- netinfo = `grep "#{interface}: " /proc/net/dev`
12
- if $?.to_i == 0
13
- _, _, rx_ok, rx_packets, rx_err, rx_drop, _, _, _, _, tx_ok, tx_packets, tx_err, tx_drop, _, _, _, _ = netinfo.split(/\s+/)
13
+ info = get_info(interface)
14
+ if info
15
+ time = Time.now.to_i
16
+ back = []
17
+ back << "#{host} net.rx_ok[#{interface}] #{time} #{info[2]}"
18
+ back << "#{host} net.rx_packets[#{interface}] #{time} #{info[3]}"
19
+ back << "#{host} net.rx_err[#{interface}] #{time} #{info[4]}"
20
+ back << "#{host} net.rx_drop[#{interface}] #{time} #{info[5]}"
21
+ back << "#{host} net.tx_ok[#{interface}] #{time} #{info[10]}"
22
+ back << "#{host} net.tx_packets[#{interface}] #{time} #{info[11]}"
23
+ back << "#{host} net.tx_err[#{interface}] #{time} #{info[12]}"
24
+ back << "#{host} net.tx_drop[#{interface}] #{time} #{info[13]}"
25
+ return back
14
26
  else
15
- Log.warn "proc not found."
16
27
  return []
17
28
  end
18
-
19
- time = Time.now.to_i
20
- back = []
21
- back << "#{host} net.rx_ok[#{interface}] #{time} #{rx_ok}"
22
- back << "#{host} net.rx_packets[#{interface}] #{time} #{rx_packets}"
23
- back << "#{host} net.rx_err[#{interface}] #{time} #{rx_err}"
24
- back << "#{host} net.rx_drop[#{interface}] #{time} #{rx_drop}"
25
- back << "#{host} net.tx_ok[#{interface}] #{time} #{tx_ok}"
26
- back << "#{host} net.tx_packets[#{interface}] #{time} #{tx_packets}"
27
- back << "#{host} net.tx_err[#{interface}] #{time} #{tx_err}"
28
- back << "#{host} net.tx_drop[#{interface}] #{time} #{tx_drop}"
29
- return back
30
-
31
29
  end
32
30
 
33
31
  def discover(*args)
@@ -35,6 +33,17 @@ module ZabbixRubyClient
35
33
  [ "net.if.discovery", "{\"{#NET_IF}\": \"#{interface}\"}" ]
36
34
  end
37
35
 
36
+ private
37
+
38
+ def get_info(interface)
39
+ info = getline("/proc/net/dev", "#{interface}: ")
40
+ if info
41
+ info.split(/\s+/)
42
+ else
43
+ false
44
+ end
45
+ end
46
+
38
47
  end
39
48
  end
40
49
  end
@@ -5,6 +5,7 @@ module ZabbixRubyClient
5
5
  module Plugins
6
6
  module Nginx
7
7
  extend self
8
+ extend ZabbixRubyClient::PluginBase
8
9
 
9
10
  def collect(*args)
10
11
  host = args[0]
@@ -0,0 +1,64 @@
1
+ require "zabbix-ruby-client/logger"
2
+
3
+ module ZabbixRubyClient
4
+ module Plugins
5
+ module Postgres
6
+ extend self
7
+
8
+ def collect(*args)
9
+ host = args[0]
10
+ psqlargs = args[1]
11
+ dbname = args[2]
12
+ # be sure to have this in the config file
13
+ # args: [ "-U username -h localhost", "dbname" ]
14
+ # and setup username in a ~/.pgpass (0600) file for the zrc user
15
+ # localhost:5432:dbname:username:password
16
+ psqlstatus = `psql #{psqlargs} -A -t -c "select * from pg_stat_database where datname='#{dbname}'" #{dbname}`
17
+ if $?.to_i == 0
18
+ status = get_status(psqlstatus)
19
+ else
20
+ Log.warn "The connection failed."
21
+ return []
22
+ end
23
+
24
+ time = Time.now.to_i
25
+ back = []
26
+ status.each do |e,v|
27
+ back << "#{host} postgres.#{e}[#{dbname}] #{time} #{v}"
28
+ end
29
+ return back
30
+ end
31
+
32
+ def discover(*args)
33
+ dbname = args[1]
34
+ [ "postgres.db.discovery", "{\"{#DBNAME}\": \"#{dbname}\"}" ]
35
+ end
36
+
37
+ def get_status(status)
38
+ ret = {}
39
+ els = status.split "|"
40
+ ret["numbackends"] = els[2]
41
+ ret["xact_commit"] = els[3]
42
+ ret["xact_rollback"] = els[4]
43
+ ret["blks_read"] = els[5]
44
+ ret["blks_hit"] = els[6]
45
+ ret["tup_returned"] = els[7]
46
+ ret["tup_fetched"] = els[8]
47
+ ret["tup_inserted"] = els[9]
48
+ ret["tup_updated"] = els[10]
49
+ ret["tup_deleted"] = els[11]
50
+ ret["conflicts"] = els[12]
51
+ ret["temp_files"] = els[13]
52
+ ret["temp_bytes"] = els[14]
53
+ ret["deadlocks"] = els[15]
54
+ ret["blk_read_time"] = els[16]
55
+ ret["blk_write_time"] = els[17]
56
+ ret
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+
63
+ ZabbixRubyClient::Plugins.register('postgres', ZabbixRubyClient::Plugins::Postgres)
64
+
@@ -1,3 +1,3 @@
1
1
  module ZabbixRubyClient
2
- VERSION ||= "0.0.17"
2
+ VERSION ||= "0.0.18"
3
3
  end
@@ -0,0 +1,11 @@
1
+ module SampleBuggy
2
+ extend self
3
+
4
+ def collect(*args)
5
+ raise Exception
6
+ end
7
+
8
+ end
9
+
10
+ ZabbixRubyClient::Plugins.register('sample_buggy', SampleBuggy)
11
+
@@ -0,0 +1,12 @@
1
+ module SampleDiscover
2
+ extend self
3
+
4
+ def discover(*args)
5
+ interface = args[0]
6
+ [ "sample.discover", "{\"{#SAMPLE}\": \"#{interface}\"}" ]
7
+ end
8
+
9
+ end
10
+
11
+ ZabbixRubyClient::Plugins.register('sample_discover', SampleDiscover)
12
+
@@ -1,9 +1,10 @@
1
1
  Total Accesses: 12
2
2
  Total kBytes: 6
3
- Uptime: 602766
4
- ReqPerSec: 1.99082e-5
5
- BytesPerSec: .010193
6
- BytesPerReq: 512
3
+ CPULoad: 5.69795e-5
4
+ Uptime: 1175861
5
+ ReqPerSec: 4.16716e-5
6
+ BytesPerSec: 1.0128
7
+ BytesPerReq: 24304.3
7
8
  BusyWorkers: 1
8
- IdleWorkers: 9
9
- Scoreboard: _____W____......................................................................................................................................................................................................................................................
9
+ IdleWorkers: 4
10
+ Scoreboard: __S__W__W_........
@@ -0,0 +1 @@
1
+ 23;14
@@ -0,0 +1 @@
1
+ /dev/sda2 288238944 76560212 197013928 28% /home
@@ -0,0 +1 @@
1
+ 8 1 sda1 974243 695335 37526290 4648644 711455 785503 27660904 11097172 0 6283844 15744924
@@ -0,0 +1 @@
1
+ 0.89 1.29 1.05 2/968 2768
@@ -0,0 +1,46 @@
1
+ MemTotal: 4130440 kB
2
+ MemFree: 224460 kB
3
+ Buffers: 59116 kB
4
+ Cached: 385776 kB
5
+ SwapCached: 204968 kB
6
+ Active: 2664148 kB
7
+ Inactive: 883200 kB
8
+ Active(anon): 2473484 kB
9
+ Inactive(anon): 739608 kB
10
+ Active(file): 190664 kB
11
+ Inactive(file): 143592 kB
12
+ Unevictable: 212 kB
13
+ Mlocked: 212 kB
14
+ HighTotal: 3280520 kB
15
+ HighFree: 41136 kB
16
+ LowTotal: 849920 kB
17
+ LowFree: 183324 kB
18
+ SwapTotal: 5858448 kB
19
+ SwapFree: 3580100 kB
20
+ Dirty: 532 kB
21
+ Writeback: 0 kB
22
+ AnonPages: 3002480 kB
23
+ Mapped: 278560 kB
24
+ Shmem: 110636 kB
25
+ Slab: 92716 kB
26
+ SReclaimable: 60300 kB
27
+ SUnreclaim: 32416 kB
28
+ KernelStack: 7752 kB
29
+ PageTables: 49584 kB
30
+ NFS_Unstable: 0 kB
31
+ Bounce: 0 kB
32
+ WritebackTmp: 0 kB
33
+ CommitLimit: 7923668 kB
34
+ Committed_AS: 15878488 kB
35
+ VmallocTotal: 122880 kB
36
+ VmallocUsed: 49400 kB
37
+ VmallocChunk: 66212 kB
38
+ HardwareCorrupted: 0 kB
39
+ AnonHugePages: 0 kB
40
+ HugePages_Total: 0
41
+ HugePages_Free: 0
42
+ HugePages_Rsvd: 0
43
+ HugePages_Surp: 0
44
+ Hugepagesize: 2048 kB
45
+ DirectMap4k: 851960 kB
46
+ DirectMap2M: 61440 kB
@@ -0,0 +1 @@
1
+ eth0: 8523363858 17554648 0 0 0 0 0 589997 2479556217 15780062 0 0 0 0 0 0
@@ -0,0 +1 @@
1
+ cpu 473806 20486 406619 187353904 11589 9 696 5186311 0 0
@@ -0,0 +1,3 @@
1
+ ---
2
+ - name: sample_discovery
3
+ args: [ 'some_arg' ]
data/spec/lib/cli_spec.rb CHANGED
@@ -4,10 +4,48 @@ require 'spec_helper'
4
4
  require "zabbix-ruby-client/cli"
5
5
 
6
6
  describe ZabbixRubyClient::Cli do
7
-
8
- pending "init creates a working directory"
9
- pending "show displays the list of data collected"
10
- pending "upload collects and uploads the data from system"
11
- pending "when a custom config file is specified it's taken in account"
12
7
 
13
- end
8
+ before :each do
9
+ @cli = ZabbixRubyClient::Cli.new(
10
+ [],
11
+ {
12
+ 'configfile' => 'config.yml',
13
+ 'taskfile' => 'minutely.yml'
14
+ }
15
+ )
16
+ @testdir = File.join('spec','files','test-client')
17
+ @cli.shell.mute do
18
+ @cli.init(@testdir)
19
+ end
20
+ @oldpwd = Dir.pwd
21
+ Dir.chdir @testdir
22
+ end
23
+
24
+ after :each do
25
+ Dir.chdir @oldpwd
26
+ FileUtils.rm_rf @testdir if Dir.exists? @testdir
27
+ end
28
+
29
+ it "init creates a working directory" do
30
+ expect(File.file? 'Gemfile').to be_true
31
+ end
32
+
33
+ it "show displays the list of data collected" do
34
+ ZabbixRubyClient::Runner.stub(:new).and_return(Object)
35
+ Object.stub(:collect)
36
+ Object.stub(:show)
37
+ @cli.shell.mute do
38
+ @cli.show
39
+ end
40
+ end
41
+
42
+ it "upload collects and uploads the data from system" do
43
+ ZabbixRubyClient::Runner.stub(:new).and_return(Object)
44
+ Object.stub(:collect)
45
+ Object.stub(:upload)
46
+ @cli.shell.mute do
47
+ @cli.upload
48
+ end
49
+ end
50
+
51
+ end
@@ -2,7 +2,64 @@
2
2
 
3
3
  require 'spec_helper'
4
4
  require "zabbix-ruby-client/data"
5
+ require "zabbix-ruby-client/plugins"
6
+ require "zabbix-ruby-client/logger"
5
7
 
6
8
  describe ZabbixRubyClient::Data do
7
9
 
8
- end
10
+ before :all do
11
+ plugindir = File.expand_path("../../files/plugins", __FILE__)
12
+ ZabbixRubyClient::Plugins.scan_dirs([plugindir])
13
+ @logfile = File.expand_path("../../files/logs/spec.log", __FILE__)
14
+ ZabbixRubyClient::Log.set_logger(@logfile)
15
+ end
16
+
17
+ before :each do
18
+ @data = ZabbixRubyClient::Data.new("host")
19
+ end
20
+
21
+ after :all do
22
+ FileUtils.rm_rf @logfile if File.exists? @logfile
23
+ end
24
+
25
+ it "initializes with host" do
26
+ expect(@data.instance_variable_get(:@host)).to eq "host"
27
+ end
28
+
29
+ it "runs a plugin" do
30
+ items = ["localhost sample[foo] 123456789 42"]
31
+ @data.run_plugin("sample")
32
+ expect(@data.instance_variable_get(:@items)).to eq items
33
+ end
34
+
35
+ it "logs an error when plugin is not found" do
36
+ ZabbixRubyClient::Log.stub(:error).with("Plugin unknown_plugin not found.")
37
+ @data.run_plugin("unknown_plugin")
38
+ end
39
+
40
+ it "runs a plugin that only has discovery" do
41
+ discovery = { "sample.discover" => [["{\"{#SAMPLE}\": \"sample_arg\"}" ]]}
42
+ @data.run_plugin("sample_discover", 'sample_arg')
43
+ expect(@data.instance_variable_get(:@discover)).to eq discovery
44
+ end
45
+
46
+ it "ignores buggy plugins" do
47
+ expect(@data.run_plugin("sample_buggy")).to be_true
48
+ end
49
+
50
+ it "logs buggy plugins" do
51
+ ZabbixRubyClient::Log.stub(:fatal).with("Oops")
52
+ ZabbixRubyClient::Log.stub(:fatal).with("Exception")
53
+ @data.run_plugin("sample_buggy")
54
+ end
55
+
56
+ it "merges collected and discovered data" do
57
+ Time.stub(:now).and_return("123456789")
58
+ @data.run_plugin("sample")
59
+ @data.run_plugin("sample_discover")
60
+ result = ["host sample.discover 123456789 { \"data\": [ {\"{#SAMPLE}\": \"\"} ] }",
61
+ "localhost sample[foo] 123456789 42"]
62
+ expect(@data.merge).to eq result
63
+ end
64
+
65
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require "zabbix-ruby-client/logger"
5
+ require "zabbix-ruby-client/plugin_base"
6
+
7
+ describe ZabbixRubyClient::PluginBase do
8
+
9
+ before :all do
10
+ @logfile = File.expand_path("../files/logs/spec.log", __FILE__)
11
+ ZabbixRubyClient::Log.set_logger(@logfile)
12
+ @stubfile = File.expand_path('../../../spec/files/system/net_dev', __FILE__)
13
+ @expected_line = "eth0: 8523363858 17554648 0 0 0 0 0 589997 2479556217 15780062 0 0 0 0 0 0"
14
+ end
15
+
16
+ after :all do
17
+ FileUtils.rm_rf @logfile if File.exists? @logfile
18
+ end
19
+
20
+ after :each do
21
+ FileUtils.rm "/tmp/xxxxx" if File.exists? "/tmp/xxxxx"
22
+ end
23
+
24
+ it "extracts a line from a file" do
25
+ line = ZabbixRubyClient::PluginBase.getline(@stubfile, "eth0: ")
26
+ expect(line).to eq @expected_line
27
+ end
28
+
29
+ it "logs a debug entry when it extracts a line from a file" do
30
+ expect(ZabbixRubyClient::Log).to receive(:debug).with("File #{@stubfile}: #{@expected_line}")
31
+ ZabbixRubyClient::PluginBase.getline(@stubfile, "eth0: ")
32
+ end
33
+
34
+ it "logs a warn entry when a line is not found in a file" do
35
+ expect(ZabbixRubyClient::Log).to receive(:warn).with("File #{@stubfile}: pattern \" xxx \" not found.")
36
+ x = ZabbixRubyClient::PluginBase.getline(@stubfile, " xxx ")
37
+ expect(x).to be_false
38
+ end
39
+
40
+ it "logs an error entry when a file is not found" do
41
+ expect(ZabbixRubyClient::Log).to receive(:error).with("File not found: /tmp/xxxxx")
42
+ x = ZabbixRubyClient::PluginBase.getline("/tmp/xxxxx", " xxx ")
43
+ expect(x).to be_false
44
+ end
45
+
46
+ it "logs an error entry when a file is not readable" do
47
+ FileUtils.touch "/tmp/xxxxx"
48
+ FileUtils.chmod 0300, "/tmp/xxxxx"
49
+ expect(ZabbixRubyClient::Log).to receive(:error).with("File not readable: /tmp/xxxxx")
50
+ x = ZabbixRubyClient::PluginBase.getline("/tmp/xxxxx", " xxx ")
51
+ expect(x).to be_false
52
+ end
53
+
54
+ end
@@ -1,14 +1,87 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'spec_helper'
4
+ require 'webmock/rspec'
4
5
  require "zabbix-ruby-client/plugins"
5
6
  ZabbixRubyClient::Plugins.scan_dirs ["zabbix-ruby-client/plugins"]
6
7
  require "zabbix-ruby-client/plugins/apache"
7
8
 
8
9
  describe ZabbixRubyClient::Plugins::Apache do
9
-
10
- pending "gets the status page from localhost"
11
- pending "populate a hash with extracted data"
12
- pending "populate scores from scoreboard data"
13
10
 
14
- end
11
+ before :each do
12
+ stubfile = File.expand_path('../../../../spec/files/system/apache_status', __FILE__)
13
+ @data = File.read(stubfile)
14
+ @processed = {
15
+ "Total Accesses"=>"12",
16
+ "Total kBytes"=>"6",
17
+ "CPULoad"=>"5.69795e-5",
18
+ "Uptime"=>"1175861",
19
+ "ReqPerSec"=>"4.16716e-5",
20
+ "BytesPerSec"=>"1.0128",
21
+ "BytesPerReq"=>"24304.3",
22
+ "BusyWorkers"=>"1",
23
+ "IdleWorkers"=>"4",
24
+ "Scoreboard"=>"__S__W__W_........"}
25
+ @expected_data = [
26
+ "local apache[TotalAccesses] 123456789 12",
27
+ "local apache[TotalKBytes] 123456789 6",
28
+ "local apache[CPULoad] 123456789 5.69795e-05",
29
+ "local apache[Uptime] 123456789 1175861",
30
+ "local apache[ReqPerSec] 123456789 4.16716e-05",
31
+ "local apache[BytesPerSec] 123456789 1.0128",
32
+ "local apache[BytesPerReq] 123456789 24304.3",
33
+ "local apache[BusyWorkers] 123456789 1",
34
+ "local apache[IdleWorkers] 123456789 4",
35
+ "local apache[c_idle] 123456789 8",
36
+ "local apache[c_waiting] 123456789 7",
37
+ "local apache[c_closing] 123456789 0",
38
+ "local apache[c_dns] 123456789 0",
39
+ "local apache[c_finish] 123456789 0",
40
+ "local apache[c_cleanup] 123456789 0",
41
+ "local apache[c_keep] 123456789 0",
42
+ "local apache[c_log] 123456789 0",
43
+ "local apache[c_read] 123456789 0",
44
+ "local apache[c_send] 123456789 2",
45
+ "local apache[c_start] 123456789 1"
46
+ ]
47
+ end
48
+
49
+ it "gets the status page from localhost" do
50
+ stub_request(:get, '127.0.0.1:80/server-status?auto')
51
+ ZabbixRubyClient::Plugins::Apache.send(:get_status)
52
+ end
53
+
54
+ it "populate a hash with extracted data" do
55
+ stub_request(:get, '127.0.0.1:80/server-status?auto').
56
+ to_return({ :body => @data })
57
+ status = ZabbixRubyClient::Plugins::Apache.send(:get_status)
58
+ expect(status).to eq @processed
59
+ end
60
+
61
+ it "populate scores from scoreboard data" do
62
+ expected = {
63
+ "_" => 7,
64
+ "S" => 1,
65
+ "R" => 0,
66
+ "W" => 2,
67
+ "K" => 0,
68
+ "D" => 0,
69
+ "C" => 0,
70
+ "L" => 0,
71
+ "G" => 0,
72
+ "I" => 0,
73
+ "." => 8
74
+ }
75
+ board = ZabbixRubyClient::Plugins::Apache.send(:get_scores, @processed['Scoreboard'])
76
+ expect(board).to eq expected
77
+ end
78
+
79
+ it "collects data properly" do
80
+ stub_request(:get, '127.0.0.1:80/server-status?auto').
81
+ to_return({ :body => @data })
82
+ Time.stub(:now).and_return("123456789")
83
+ data = ZabbixRubyClient::Plugins::Apache.send(:collect, 'local')
84
+ expect(data).to eq @expected_data
85
+ end
86
+
87
+ end