zabbix_nudge 0.1.3

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.
@@ -0,0 +1,79 @@
1
+ require "zabbix_nudge/version"
2
+ require "active_support/core_ext/string/inflections.rb"
3
+ require 'nokogiri'
4
+ require 'yajl/json_gem'
5
+ require 'zabbix'
6
+ require "socket"
7
+ require "zabbix_nudge/jmx"
8
+
9
+ module ZabbixNudge
10
+
11
+ def self.root
12
+ @root ="#{File.expand_path('../..',__FILE__)}"
13
+ end
14
+
15
+ class Nudge
16
+ def initialize(templates, options = {} )
17
+ options[:zabbix_server_name] = 'localhost' unless options[:zabbix_server_name]
18
+ options[:zabbix_server_port] = '10051' unless options[:zabbix_server_port]
19
+ options[:sender_hostname] = Socket.gethostname unless options[:sender_hostname]
20
+
21
+ @options = options
22
+ @templates = template_files(templates)
23
+ @items = template_items(@templates)
24
+ end
25
+
26
+ def template_files(templates)
27
+ template_files = []
28
+ template_files = Dir.glob(File.join(templates,'*.xml')) if !templates.is_a?(Array) && File.directory?(templates)
29
+ template_files = templates.map{ |template| template if File.exist?(template) }.compact if templates.is_a?(Array)
30
+ template_files = [templates] if !templates.is_a?(Array) && File.exist?(templates) && !File.directory?(templates)
31
+ template_files
32
+ end
33
+
34
+ def template_items(templates)
35
+ parsed_items = Hash.new
36
+
37
+ templates.each do |template|
38
+ template_items = Nokogiri::XML(File.open(template))
39
+ items = template_items.xpath('//item').map {|item| item.attributes['key'].text}.compact
40
+ items.each do |item|
41
+ parts = item.match(/([^\[]+)\[([^\]]+)/)
42
+ unless parts.nil?
43
+ key = parts[1].underscore.to_sym
44
+ attributes = parts[2]
45
+ (parsed_items[key]) ? parsed_items[key] << attributes : parsed_items[key] = [attributes]
46
+ else
47
+ puts "not evaluating: "+item
48
+ end
49
+ end
50
+ end
51
+ parsed_items
52
+ end
53
+
54
+ def send(items = :all)
55
+
56
+ return if @items.nil?
57
+
58
+
59
+ pushers = ( items == :all) ? ( @items.keys.map{ |key| "ZabbixNudge::#{key.to_s.camelize}".constantize }) : ["ZabbixNudge::#{items.camelize}".constantize]
60
+
61
+ processed_items = Hash.new
62
+
63
+ pushers.map do |pusher|
64
+ pusher_key = pusher.to_s.demodulize.underscore.to_sym
65
+ processed_items.update pusher.new(@items[pusher_key],@options[pusher_key]).send(:processed_items)
66
+ end
67
+
68
+ zbx = Zabbix::Sender::Buffer.new :host => @options[:zabbix_server_name], :port => @options[:zabbix_server_port]
69
+
70
+ processed_items.each do |key,value|
71
+ zbx.append key, value, :host => @options[:sender_hostname]
72
+ end
73
+ zbx.flush
74
+
75
+ processed_items
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,61 @@
1
+ require 'httparty'
2
+
3
+ module ZabbixNudge
4
+
5
+ class Jmx
6
+
7
+ include HTTParty
8
+ base_uri 'http://localhost:8080'
9
+ format :json
10
+
11
+ def initialize(items=[] ,options={})
12
+ self.class.base_uri options[:base_uri] if options[:base_uri]
13
+ @payload = Array.new
14
+ @items = items
15
+ @items.each do |item| mbean,attribute,path = item.split(';')
16
+ tokens = { "mbean" => mbean, "attribute" => attribute, "type" => "READ"}
17
+ tokens["path"] = path if path
18
+ @payload << tokens
19
+ end
20
+ end
21
+
22
+ # http://www.jolokia.org/reference/html/protocol.html#search
23
+
24
+ def search(mbean,config={})
25
+ self.class.post('/jolokia', :body => { "type" => "SEARCH", "mbean" => mbean, "config" => config}.to_json)
26
+ end
27
+
28
+ # http://www.jolokia.org/reference/html/protocol.html#list
29
+ # use options = { "maxDepth" => 2} to limit depth
30
+
31
+ def list(path,config={})
32
+ self.class.post('/jolokia', :body => { "type" => "LIST", "path" => path, "config" => config}.to_json)
33
+ end
34
+
35
+ def read(mbean,attribute,path=nil,config={})
36
+ payload = { "type" => "READ", "mbean" => mbean, "attribute" => attribute}
37
+ payload["path"] = path if path
38
+ payload["config"] = config if config.length > 0
39
+ ap payload.to_json
40
+ self.class.post('/jolokia', :body => payload.to_json, :timeout => 5)
41
+ end
42
+
43
+ def version
44
+ self.class.post('/jolokia', :body => { "type" => "VERSION"}.to_json)
45
+ end
46
+
47
+ def processed_items
48
+ data = self.class.post('/jolokia', :body => @payload.to_json, :timeout => 5) rescue nil
49
+ result = Hash.new
50
+ data.each{|datum| result[result_key(datum)] = datum['value'] if datum['request']} if data
51
+ result
52
+ end
53
+
54
+ private
55
+
56
+ def result_key(datum)
57
+ "#{self.class.to_s.demodulize.underscore}[#{datum['request']['mbean']};#{datum['request']['attribute']};#{datum['request']['path']}]"
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,54 @@
1
+ require 'mixlib/cli'
2
+
3
+ module ZabbixNudge
4
+ class NudgeCLI
5
+ include Mixlib::CLI
6
+
7
+ option :jmx__base_uri,
8
+ :long => "--jmx_base_uri uri",
9
+ :description => "The jmx base uri"
10
+
11
+ end
12
+
13
+ class JmxCLI
14
+ include Mixlib::CLI
15
+
16
+ option :base_uri,
17
+ :short => "-b uri",
18
+ :default => "localhost:8080",
19
+ :long => "--base_uri uri",
20
+ :description => "The jmx base uri"
21
+
22
+ option :command,
23
+ :short => "-o command",
24
+ :default => "read",
25
+ :long => "--command action",
26
+ :description => "The command to perform",
27
+ :proc => Proc.new { |o| o.to_sym }
28
+
29
+ option :mbean,
30
+ :short => "-m mbean",
31
+ :long => "--mbean mbean",
32
+ :description => "The name of the mbean e.g. java.lang:type=Memory (needed for read command)"
33
+
34
+ option :attribute,
35
+ :short => "-a attribute",
36
+ :long => "--attribute attribute",
37
+ :description => "The name of the action e.g. HeapMemoryUsage (needed for read command)"
38
+
39
+ option :path,
40
+ :short => "-p path",
41
+ :long => "--path path",
42
+ :description => "The name of the path e.g. used (needed for read and list command)"
43
+
44
+ option :help,
45
+ :short => "-h",
46
+ :long => "--help",
47
+ :description => "Show this message",
48
+ :on => :tail,
49
+ :boolean => true,
50
+ :show_options => true,
51
+ :exit => 0
52
+
53
+ end
54
+ end
@@ -0,0 +1,74 @@
1
+ require 'mixlib/cli'
2
+ require 'socket'
3
+
4
+ module ZabbixNudge
5
+ class NudgeCLI
6
+ include Mixlib::CLI
7
+ include Socket
8
+
9
+ option :config_file,
10
+ :short => "-c CONFIG",
11
+ :long => "--config CONFIG",
12
+ :default => '/etc/zabbix-nudge/config.rb',
13
+ :description => "The configuration file to use"
14
+
15
+ option :templates,
16
+ :short => "-t FILE",
17
+ :long => "--template FILE",
18
+ :default => File.join(ZabbixNudge.root,"examples"),
19
+ :description => "The template file(s) to use, can be a file a comma separated list of files or a directory",
20
+ :proc => Proc.new { |t| (t =~ /,/) ? t.split(',') : t }
21
+
22
+ option :zabbix_server_name,
23
+ :short => "-z SERVER",
24
+ :long => "--zabbix-server SERVER",
25
+ :default => 'localhost',
26
+ :description => "Hostname or IP address of Zabbix Server. Default is localhost"
27
+
28
+ option :zabbix_server_port,
29
+ :short => "-p SERVER PORT",
30
+ :long => "--port SERVER PORT",
31
+ :default => '10051',
32
+ :description => "Specify port number of server trapper running on the server. Default is 10051"
33
+
34
+ option :sender_hostname,
35
+ :short => "-s HOST",
36
+ :long => "--host HOSTNAME",
37
+ :default => Socket.gethostname,
38
+ :description => "Specify host name. Default is current hostname"
39
+
40
+ option :jolokia_hostname,
41
+ :short => "-P JHOSTNAME",
42
+ :long => "--jolokiahostname JHOSTNAME",
43
+ :default => "localhost",
44
+ :description => "Specify jolokia hostname. Default is localhost"
45
+
46
+ option :jolokia_port,
47
+ :short => "-P JPORT",
48
+ :long => "--jolokiaport JPORT",
49
+ :default => "8080",
50
+ :description => "Specify jolokia port. Default is 8080."
51
+
52
+ option :log_level,
53
+ :short => "-l LEVEL",
54
+ :long => "--log_level LEVEL",
55
+ :description => "Set the log level (debug, info, warn, error, fatal)",
56
+ :proc => Proc.new { |l| l.to_sym }
57
+
58
+ option :show_send_values,
59
+ :short => "-v",
60
+ :long => "--show_send_values",
61
+ :description => "shows what values got send to zabbix",
62
+ :boolean => true
63
+
64
+ option :help,
65
+ :short => "-h",
66
+ :long => "--help",
67
+ :description => "Show this message",
68
+ :on => :tail,
69
+ :boolean => true,
70
+ :show_options => true,
71
+ :exit => 0
72
+
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module ZabbixNudge
2
+ VERSION = "0.1.3"
3
+ end
@@ -0,0 +1,7 @@
1
+ HTTP/1.1 200 OK
2
+ Server: Apache-Coyote/1.1
3
+ Content-Type: text/plain;charset=utf-8
4
+ Content-Length: 512
5
+ Date: Wed, 15 Jun 2011 15:17:12 GMT
6
+
7
+ [{"timestamp":1308151032,"status":200,"request":{"mbean":"java.lang:name=CMS Perm Gen,type=MemoryPool","path":"committed","attribute":"Usage","type":"read"},"value":31518720},{"timestamp":1308151032,"status":200,"request":{"mbean":"java.lang:name=CMS Perm Gen,type=MemoryPool","path":"max","attribute":"Usage","type":"read"},"value":67108864},{"timestamp":1308151032,"status":200,"request":{"mbean":"java.lang:name=CMS Perm Gen,type=MemoryPool","path":"used","attribute":"Usage","type":"read"},"value":18890360}]
@@ -0,0 +1,92 @@
1
+ <?xml version="1.0"?>
2
+ <zabbix_export version="1.0" date="22.12.07" time="03.42">
3
+ <hosts>
4
+ <host name="Template_Tomcat">
5
+ <proxy_hostid>0</proxy_hostid>
6
+ <useip>0</useip>
7
+ <dns/>
8
+ <ip>0.0.0.0</ip>
9
+ <port>0</port>
10
+ <status>3</status>
11
+ <groups>
12
+ <group>Templates</group>
13
+ <group>Web Server</group>
14
+ </groups>
15
+ <items>
16
+ <item type="7" key="jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;committed]" value_type="3">
17
+ <description>memorypool cms perm gen committed</description>
18
+ <delay>30</delay>
19
+ <history>90</history>
20
+ <trends>365</trends>
21
+ <units>B</units>
22
+ <formula>1</formula>
23
+ <snmp_community>public</snmp_community>
24
+ <snmp_oid>interfaces.ifTable.ifEntry.ifInOctets.1</snmp_oid>
25
+ <snmp_port>161</snmp_port>
26
+ </item>
27
+ <item type="7" key="jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;max]" value_type="3">
28
+ <description>memorypool cms perm gen max</description>
29
+ <delay>3600</delay>
30
+ <history>90</history>
31
+ <trends>365</trends>
32
+ <units>B</units>
33
+ <formula>1</formula>
34
+ <snmp_community>public</snmp_community>
35
+ <snmp_oid>interfaces.ifTable.ifEntry.ifInOctets.1</snmp_oid>
36
+ <snmp_port>161</snmp_port>
37
+ </item>
38
+ <item type="7" key="jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;used]" value_type="3">
39
+ <description>memorypool cms perm gen used</description>
40
+ <delay>30</delay>
41
+ <history>90</history>
42
+ <trends>365</trends>
43
+ <units>B</units>
44
+ <formula>1</formula>
45
+ <snmp_community>public</snmp_community>
46
+ <snmp_oid>interfaces.ifTable.ifEntry.ifInOctets.1</snmp_oid>
47
+ <snmp_port>161</snmp_port>
48
+ </item>
49
+ </items>
50
+ <triggers/>
51
+ <graphs>
52
+ <graph name="memorypool cms perm gen" width="900" height="200">
53
+ <show_work_period>1</show_work_period>
54
+ <show_triggers>1</show_triggers>
55
+ <ymin_type>0</ymin_type>
56
+ <ymax_type>0</ymax_type>
57
+ <ymin_item_key></ymin_item_key>
58
+ <ymax_item_key></ymax_item_key>
59
+ <show_work_period>0</show_work_period>
60
+ <show_triggers>0</show_triggers>
61
+ <graphtype>1</graphtype>
62
+ <yaxismin>0.0000</yaxismin>
63
+ <yaxismax>100.0000</yaxismax>
64
+ <show_legend>0</show_legend>
65
+ <show_3d>0</show_3d>
66
+ <percent_left>0.0000</percent_left>
67
+ <percent_right>0.0000</percent_right>
68
+ <graph_elements>
69
+ <graph_element item="{HOSTNAME}:jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;committed]">
70
+ <color>000099</color>
71
+ <yaxisside>1</yaxisside>
72
+ <calc_fnc>2</calc_fnc>
73
+ <periods_cnt>5</periods_cnt>
74
+ </graph_element>
75
+ <graph_element item="{HOSTNAME}:jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;max]">
76
+ <color>990000</color>
77
+ <yaxisside>1</yaxisside>
78
+ <calc_fnc>2</calc_fnc>
79
+ <periods_cnt>5</periods_cnt>
80
+ </graph_element>
81
+ <graph_element item="{HOSTNAME}:jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;used]">
82
+ <color>009900</color>
83
+ <yaxisside>1</yaxisside>
84
+ <calc_fnc>2</calc_fnc>
85
+ <periods_cnt>5</periods_cnt>
86
+ </graph_element>
87
+ </graph_elements>
88
+ </graph>
89
+ </graphs>
90
+ </host>
91
+ </hosts>
92
+ </zabbix_export>
@@ -0,0 +1,13 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $: << File.join(File.dirname(__FILE__), "/../lib")
4
+ require 'zabbix_nudge'
5
+ require 'fakeweb'
6
+
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ def fixture_file(filename)
10
+ return '' if filename == ''
11
+ file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
12
+ File.read(file_path)
13
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.join(File.dirname(__FILE__), "/spec_helper")
4
+ require 'ap'
5
+
6
+ describe ZabbixNudge::Nudge do
7
+
8
+ context 'Initialization' do
9
+
10
+ FakeWeb.register_uri(:post, "http://localhost:4568/jolokia", :response => fixture_file("cms_perm_response.txt"))
11
+
12
+ it 'should accept a template file' do
13
+ @m = ZabbixNudge::Nudge.new(File.join(File.dirname(__FILE__), 'fixtures/tomcat_template.xml'),:jmx => {:base_uri => "http://localhost:4568"})
14
+ @m.send.should == {"jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;max]"=>67108864, "jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;used]"=>18890360, "jmx[java.lang:name=CMS Perm Gen,type=MemoryPool;Usage;committed]"=>31518720}
15
+
16
+ end
17
+
18
+ end
19
+
20
+ context 'process items' do
21
+
22
+
23
+ before(:each) do
24
+ end
25
+
26
+ it "should get the title" do
27
+ end
28
+
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "zabbix_nudge/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "zabbix_nudge"
8
+ s.version = ZabbixNudge::VERSION
9
+ s.authors = ["Myroslav Rys"]
10
+ s.email = ["stonevil@gmail.com"]
11
+ s.homepage = "http://www.stone.org.ua"
12
+ s.license = 'GPL'
13
+
14
+ s.summary = %q{Collect metrics from different sources and push (nudge) data to Zabbix}
15
+ s.description = %q{zabbix-nudge is a gem to collect metrics from different sources, parse zabbix templates and push (nudge) the data to zabbix proxy or server}
16
+
17
+ s.rubyforge_project = "zabbix-nudge"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_dependency 'nokogiri', '~> 1.4.4'
25
+ s.add_dependency 'zabbix', '~> 0.3.0'
26
+ s.add_dependency 'httparty', '~> 0.7.8'
27
+ s.add_dependency 'activesupport', '~> 3.0.8'
28
+ s.add_dependency "i18n", "~> 0.6.0"
29
+ s.add_dependency 'yajl-ruby', '~> 0.8.2'
30
+ s.add_dependency "awesome_print", "~> 0.4.0"
31
+ s.add_dependency "mixlib-cli", "~> 1.2.0"
32
+ s.add_dependency "daemons", "~> 1.1.9"
33
+
34
+ s.add_development_dependency 'rspec', '~> 2.6.0'
35
+ s.add_development_dependency 'fakeweb', '~> 1.3.0'
36
+
37
+ end