zabbix-ruby-client 0.0.17 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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