circonus 1.0.1

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,131 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Update an nginx graph from a list of hosts attached to a template *HACK*
4
+ # update_nginx_graph.rb template_name graphid
5
+ # --FIXME probably not the best way to get a list of hosts.. working on a better way
6
+ #
7
+ # -- David Nicklay
8
+ #
9
+
10
+ require 'rubygems'
11
+ require 'circonus'
12
+ require "#{ENV['HOME']}/.circonus.rb"
13
+ @c = Circonus.new(@apitoken,@appname,@agent)
14
+
15
+ if ((ARGV.length < 1) or ARGV[0].match('^-')) then
16
+ print "Usage: update_nginx_graph.rb template_name [graphid]\n"
17
+ exit(-1)
18
+ end
19
+ template_name = ARGV[0]
20
+ graphid = ARGV[1]
21
+
22
+ agents = @c.list_broker
23
+ agentid = agents.select { |a| a['_name'] == @agent }.first['_cid']
24
+
25
+ title = "#{template_name} - requests"
26
+ data = {
27
+ "title"=>"nginx #{title}",
28
+ "style"=>"area",
29
+ "max_right_y"=>nil,
30
+ "min_right_y"=>nil,
31
+ "min_left_y"=>nil,
32
+ "max_left_y"=>nil,
33
+ "guides"=>[],
34
+ "datapoints"=> [],
35
+ "composites"=> []
36
+ }
37
+
38
+ dpstub = {
39
+ "axis"=>"l",
40
+ "stack"=>nil,
41
+ "metric_type"=>"numeric",
42
+ "data_formula"=>nil,
43
+ "name"=>nil,
44
+ "derive"=>"counter",
45
+ "metric_name"=>nil,
46
+ "color"=>"#33aa33",
47
+ "check_id"=>nil,
48
+ "legend_formula"=>nil,
49
+ "hidden"=>false
50
+ }
51
+
52
+ # No SUM(*) is available, so we have to generate a formula ourselves:
53
+ # Generate a total formula =A+B+C...... using the number of datapoints
54
+ def get_total_formula(npoints)
55
+ i = 0
56
+ formula = "="
57
+ a = 'A'..'ZZZZ'
58
+ a.each do |x|
59
+ i += 1
60
+ formula += x
61
+ break if i == npoints
62
+ formula += "+"
63
+ end
64
+ return formula
65
+ end
66
+
67
+ # get unique values from an array of hashes given an index to compare on
68
+ def get_unique(array,index)
69
+ a = array.sort_by { |x| x[index] }
70
+ return a.inject([]) do |result,item|
71
+ result << item if !result.last||result.last[index]!=item[index]
72
+ result
73
+ end
74
+ end
75
+
76
+ # Get list of hosts on template
77
+ hosts = @c.list_template.select { |t| t['name'] == template_name }.first['hosts']
78
+ # Get list of check ids to use:
79
+ bundles = @c.list_check_bundle().select { |b| hosts.include? b['target'] }
80
+ checkids = get_unique(bundles,'target').map { |j| j['_checks'].first }
81
+ checkids.each do |checkid|
82
+ cid = checkid.to_a.first.gsub(/^.*\//,'')
83
+ %w{ requests }.each do |metric|
84
+ dp = dpstub.clone
85
+ dp['name'] = "nginx #{title} - #{metric}"
86
+ dp['metric_name'] = metric
87
+ if %w{ accepted handled requests }.include? metric then
88
+ dp['derive'] = "counter"
89
+ end
90
+ dp['color'] = nil
91
+
92
+ dp['stack'] = 0
93
+ dp['check_id'] = cid
94
+ dp['hidden'] = true
95
+
96
+ data['datapoints'] << dp
97
+ end
98
+ end
99
+
100
+
101
+
102
+ # Do composite total:
103
+ formula = get_total_formula(data['datapoints'].length)
104
+ totaldp = {
105
+ "name"=>"Total Reqs/s",
106
+ "axis"=>"l",
107
+ "stack"=>nil,
108
+ "legend_formula"=>"=ceil(VAL)",
109
+ "color"=>"#33aa33",
110
+ "data_formula"=>formula,
111
+ "hidden"=>false
112
+ }
113
+ data['composites'] << totaldp
114
+
115
+
116
+ guidepct = {
117
+ "data_formula"=>"99%",
118
+ "name"=>"99th Percentile",
119
+ "color"=>"#ea3a92",
120
+ "hidden"=>false,
121
+ "legend_formula"=>"=ceil(VAL)"
122
+ }
123
+ data['guides'] << guidepct
124
+
125
+ if graphid.nil? then
126
+ r = @c.add_graph(data)
127
+ else
128
+ r = @c.update_graph(graphid,data)
129
+ end
130
+ pp r
131
+
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+ # Add a single nginx host to circonus
3
+
4
+ require 'rubygems'
5
+ require 'circonus'
6
+ require 'optparse'
7
+ require "#{ENV['HOME']}/.circonus.rb"
8
+
9
+ def do_update_check_bundle(data)
10
+ search_check_bundle = @c.list_check_bundle({'display_name' => data['display_name']})
11
+ existing = false
12
+ if search_check_bundle.any? # already exists...
13
+ existing = true
14
+ r = @c.update_check_bundle(search_check_bundle.first['_cid'],data)
15
+ else
16
+ r = @c.add_check_bundle(data)
17
+ end
18
+ if not r.nil? then
19
+ pp r
20
+ print "Success (#{existing ? 'updating' : 'adding'} #{data['display_name']})\n"
21
+ end
22
+ end
23
+
24
+
25
+ options = {}
26
+ options[:tags] = []
27
+ OptionParser.new { |opts|
28
+ opts.banner = "Usage: #{File.basename($0)} [-h] hostname [-t tag1,tag2,...]\n"
29
+ opts.on( '-h', '--help', "This usage menu") do
30
+ puts opts
31
+ exit
32
+ end
33
+ opts.on( '-t','--tags TAGLIST',"Apply comma separated list of tags" ) do |t|
34
+ options[:tags] += t.split(/,/)
35
+ end
36
+ }.parse!
37
+
38
+ def usage()
39
+ print <<EOF
40
+ Usage: #{File.basename($0)} hostname [-t tag1,tag2,... ]
41
+ -h,--help This usage menu
42
+ -t,--tags Comma separated list of tag names to apply (default is an empty list)
43
+ EOF
44
+ end
45
+
46
+ host = ARGV[0]
47
+ if host.nil? then
48
+ usage()
49
+ exit -1
50
+ end
51
+
52
+ @c = Circonus.new(@apitoken,@appname,@agent)
53
+
54
+ agents = @c.list_broker
55
+ agentid = agents.select { |a| a['_name'] == @agent }.first['_cid']
56
+
57
+ print "Adding nginx for host #{host}\n"
58
+ data = {
59
+ :agent_id => agentid,
60
+ :target => host,
61
+ :module => "nginx",
62
+ }
63
+ bundle = {
64
+ "type" => "nginx",
65
+ "target" => host,
66
+ "tags" => options[:tags],
67
+ "timeout" => 10,
68
+ "period" => 60,
69
+ "display_name" => "#{host} nginx",
70
+ "brokers" => [
71
+ agentid
72
+ ],
73
+ "metrics" => [
74
+ ],
75
+ "config" => {
76
+ "url" => "http://#{host}/server-status"
77
+ }
78
+ }
79
+ %w{ handled waiting requests accepted active duration reading writing }.each do |metric|
80
+ bundle['metrics'] << {
81
+ 'type' => 'numeric',
82
+ 'name' => metric
83
+ }
84
+ end
85
+
86
+ do_update_check_bundle(bundle)
87
+
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+ # Add a single snmp based host to circonus
3
+
4
+ require 'rubygems'
5
+ require 'circonus'
6
+ require 'snmp'
7
+ require 'pp'
8
+ require 'optparse'
9
+
10
+
11
+ options = {}
12
+ options[:tags] = []
13
+ OptionParser.new { |opts|
14
+ opts.banner = "Usage: #{File.basename($0)} [-h] hostname [-t tag1,tag2,...]\n"
15
+ opts.on( '-h', '--help', "This usage menu") do
16
+ puts opts
17
+ exit
18
+ end
19
+ opts.on( '-t','--tags TAGLIST',"Apply comma separated list of tags" ) do |t|
20
+ options[:tags] += t.split(/,/)
21
+ end
22
+ }.parse!
23
+
24
+
25
+ def usage()
26
+ print <<EOF
27
+ Usage: add_snmp_node.rb hostname [-t tag1,tag2,... ]
28
+ -h,--help This usage menu
29
+ -t,--tags Comma separated list of tag names to apply (default is an empty list)
30
+ EOF
31
+ end
32
+
33
+ host = ARGV[0]
34
+ if host.nil? then
35
+ usage()
36
+ exit -1
37
+ end
38
+
39
+
40
+ # Make a guess as to what ethernet interface to query for data
41
+ def get_ethernet_oids(host)
42
+ ifTable_columns = ["ifDescr", "ifOutOctets","ifIndex"]
43
+ eth_name = nil
44
+ eth_octets = nil
45
+ eth_index = nil
46
+ SNMP::Manager.open(:Host => host) do |manager|
47
+ manager.walk(ifTable_columns) do |row|
48
+ next if row[0].value.to_s.match('^lo')
49
+ if eth_name.nil? then
50
+ eth_name = row[0].value
51
+ eth_octets = row[1].value
52
+ eth_index = row[2].value
53
+ end
54
+ if row[1].value > eth_octets then
55
+ eth_name = row[0].value
56
+ eth_octets = row[1].value
57
+ eth_index = row[2].value
58
+ end
59
+ end
60
+ end
61
+ if eth_index.nil?
62
+ eth_index = 0
63
+ end
64
+ return {
65
+ "ifOutOctets" => ".1.3.6.1.2.1.2.2.1.16.#{eth_index}",
66
+ "ifInOctets" => ".1.3.6.1.2.1.2.2.1.10.#{eth_index}"
67
+ }
68
+ end
69
+
70
+ require "#{ENV['HOME']}/.circonus.rb"
71
+ @c = Circonus.new(@apitoken,@appname,@agent)
72
+
73
+ agentid = @c.search_broker(@agent,'_name').first['_cid']
74
+
75
+ print "Adding snmp check for host #{host}\n"
76
+ data_stub = {
77
+ "type" => nil,
78
+ "target" => nil,
79
+ "timeout" => 10,
80
+ "period" => 60,
81
+ "display_name" => nil,
82
+ "brokers" => [],
83
+ "metrics" => [],
84
+ "config" => {}
85
+ }
86
+ bundle = data_stub.clone()
87
+ bundle['tags'] = options[:tags]
88
+ bundle['target'] = host
89
+ bundle['type'] = 'snmp'
90
+ bundle['display_name'] = "#{host} snmp"
91
+ bundle['brokers'] << agentid
92
+ bundle['config'] = {
93
+ "community" => "public",
94
+ "version" => "2c",
95
+ "port" => "161",
96
+ }
97
+ oids = {
98
+ "memAvailSwap"=> ".1.3.6.1.4.1.2021.4.4.0",
99
+ "memAvailReal"=> ".1.3.6.1.4.1.2021.4.6.0",
100
+ "memTotalSwap"=> ".1.3.6.1.4.1.2021.4.3.0",
101
+ "memTotalReal"=> ".1.3.6.1.4.1.2021.4.5.0",
102
+ "memTotalFree"=> ".1.3.6.1.4.1.2021.4.11.0",
103
+ "memShared"=> ".1.3.6.1.4.1.2021.4.13.0",
104
+ "memBuffer"=> ".1.3.6.1.4.1.2021.4.14.0",
105
+ "memCached"=> ".1.3.6.1.4.1.2021.4.15.0",
106
+ "ssCpuRawUser"=> ".1.3.6.1.4.1.2021.11.50.0",
107
+ "ssCpuRawNice"=> ".1.3.6.1.4.1.2021.11.51.0",
108
+ "ssCpuRawSystem"=> ".1.3.6.1.4.1.2021.11.52.0",
109
+ "ssCpuRawIdle"=> ".1.3.6.1.4.1.2021.11.53.0",
110
+ "ssCpuRawWait"=> ".1.3.6.1.4.1.2021.11.54.0",
111
+ "ssCpuRawKernel"=> ".1.3.6.1.4.1.2021.11.55.0",
112
+ "ssCpuRawInterrupt"=> ".1.3.6.1.4.1.2021.11.56.0",
113
+ "ssCpuRawSoftIRQ"=> ".1.3.6.1.4.1.2021.11.61.0",
114
+ "ssCpuIdle"=> ".1.3.6.1.4.1.2021.11.11.0"
115
+ }
116
+
117
+ begin
118
+ eth_oids = get_ethernet_oids(host)
119
+ rescue
120
+ eth_oids = {}
121
+ end
122
+ oids.merge!(eth_oids)
123
+
124
+ oids.each do |name,oid|
125
+ bundle['config']["oid_#{name}"] = oid
126
+ bundle['metrics'] << {
127
+ 'type' => 'numeric',
128
+ 'name' => name
129
+ }
130
+ end
131
+
132
+ search_bundles = @c.search_check_bundle(bundle['display_name'],'display_name')
133
+ if search_bundles.any? # already exists...
134
+ r = @c.update_check_bundle(search_bundles.first['_cid'],bundle)
135
+ else
136
+ r = @c.add_check_bundle(bundle)
137
+ end
138
+ if not r.nil? then
139
+ print "Success\n"
140
+ #pp r
141
+ end
142
+
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # Make a cached copy of all of what is in circonus API
3
+
4
+ require 'rubygems'
5
+ require 'circonus'
6
+ require 'json'
7
+ require "#{ENV['HOME']}/.circonus.rb"
8
+ @c = Circonus.new(@apitoken,@appname,@agent)
9
+
10
+ @c.methods.select { |m| m.match('^list_') }.each do |m|
11
+ begin
12
+ data = @c.send m.to_sym
13
+ type = m.sub('list_','')
14
+ Dir.mkdir 'cache' unless File.directory?('cache')
15
+ f = File.open File.join('cache',"#{type}.json"), "w"
16
+ f.write JSON.pretty_generate(data)
17
+ f.close
18
+ rescue RestClient::ResourceNotFound => e
19
+ end
20
+ end
21
+
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Update an nginx graph from a list of hosts attached to a template *HACK*
4
+ # update_nginx_graph.rb template_name graphid
5
+ # --FIXME probably not the best way to get a list of hosts.. working on a better way
6
+ #
7
+ # -- David Nicklay
8
+ #
9
+
10
+ require 'rubygems'
11
+ require 'circonus'
12
+ require "#{ENV['HOME']}/.circonus.rb"
13
+ @c = Circonus.new(@apitoken,@appname,@agent)
14
+
15
+ if ((ARGV.length < 1) or ARGV[0].match('^-')) then
16
+ print "Usage: update_nginx_graph.rb template_name [graphid]\n"
17
+ exit(-1)
18
+ end
19
+ template_name = ARGV[0]
20
+ graphid = ARGV[1]
21
+
22
+ agents = @c.list_broker
23
+ agentid = agents.select { |a| a['_name'] == @agent }.first['_cid']
24
+
25
+ title = "#{template_name} - requests"
26
+ data = {
27
+ "title"=>"nginx #{title}",
28
+ "style"=>"area",
29
+ "max_right_y"=>nil,
30
+ "min_right_y"=>nil,
31
+ "min_left_y"=>nil,
32
+ "max_left_y"=>nil,
33
+ "guides"=>[],
34
+ "datapoints"=> [],
35
+ "composites"=> []
36
+ }
37
+
38
+ dpstub = {
39
+ "axis"=>"l",
40
+ "stack"=>nil,
41
+ "metric_type"=>"numeric",
42
+ "data_formula"=>nil,
43
+ "name"=>nil,
44
+ "derive"=>"counter",
45
+ "metric_name"=>nil,
46
+ "color"=>"#33aa33",
47
+ "check_id"=>nil,
48
+ "legend_formula"=>nil,
49
+ "hidden"=>false
50
+ }
51
+
52
+ # No SUM(*) is available, so we have to generate a formula ourselves:
53
+ # Generate a total formula =A+B+C...... using the number of datapoints
54
+ def get_total_formula(npoints)
55
+ i = 0
56
+ formula = "="
57
+ a = 'A'..'ZZZZ'
58
+ a.each do |x|
59
+ i += 1
60
+ formula += x
61
+ break if i == npoints
62
+ formula += "+"
63
+ end
64
+ return formula
65
+ end
66
+
67
+ # get unique values from an array of hashes given an index to compare on
68
+ def get_unique(array,index)
69
+ a = array.sort_by { |x| x[index] }
70
+ return a.inject([]) do |result,item|
71
+ result << item if !result.last||result.last[index]!=item[index]
72
+ result
73
+ end
74
+ end
75
+
76
+ # Get list of hosts on template
77
+ hosts = @c.list_template.select { |t| t['name'] == template_name }.first['hosts']
78
+ # Get list of check ids to use:
79
+ bundles = @c.list_check_bundle().select { |b| hosts.include? b['target'] }
80
+ checkids = get_unique(bundles,'target').map { |j| j['_checks'].first }
81
+ checkids.each do |checkid|
82
+ cid = checkid.to_a.first.gsub(/^.*\//,'')
83
+ %w{ requests }.each do |metric|
84
+ dp = dpstub.clone
85
+ dp['name'] = "nginx #{title} - #{metric}"
86
+ dp['metric_name'] = metric
87
+ if %w{ accepted handled requests }.include? metric then
88
+ dp['derive'] = "counter"
89
+ end
90
+ dp['color'] = nil
91
+
92
+ dp['stack'] = 0
93
+ dp['check_id'] = cid
94
+ dp['hidden'] = true
95
+
96
+ data['datapoints'] << dp
97
+ end
98
+ end
99
+
100
+
101
+
102
+ # Do composite total:
103
+ formula = get_total_formula(data['datapoints'].length)
104
+ totaldp = {
105
+ "name"=>"Total Reqs/s",
106
+ "axis"=>"l",
107
+ "stack"=>nil,
108
+ "legend_formula"=>"=ceil(VAL)",
109
+ "color"=>"#33aa33",
110
+ "data_formula"=>formula,
111
+ "hidden"=>false
112
+ }
113
+ data['composites'] << totaldp
114
+
115
+
116
+ guidepct = {
117
+ "data_formula"=>"99%",
118
+ "name"=>"99th Percentile",
119
+ "color"=>"#ea3a92",
120
+ "hidden"=>false,
121
+ "legend_formula"=>"=ceil(VAL)"
122
+ }
123
+ data['guides'] << guidepct
124
+
125
+ if graphid.nil? then
126
+ r = @c.add_graph(data)
127
+ else
128
+ r = @c.update_graph(graphid,data)
129
+ end
130
+ pp r
131
+