circonus 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ # CLI for circonus API
3
+ # Most things can be accessed with list_*, get_*, add_*
4
+
5
+ require 'rubygems'
6
+ require 'circonus'
7
+ require 'pp'
8
+ require 'ripl'
9
+
10
+ # You need to have thse in a ~/.circonus.rb file
11
+ #@agent="mytestbroker"
12
+ #@apitoken="blahblahblah"
13
+ #@appname="curl"
14
+
15
+ require "#{ENV['HOME']}/.circonus.rb"
16
+
17
+ @c = Circonus.new(@apitoken,@appname,@agent)
18
+
19
+ def help()
20
+ return methods().select { |m| m.to_s.match('^(list|get|add|delete|update|search)_') }.sort.join(' ')
21
+ end
22
+
23
+ #def list(arg)
24
+ # self.send "list_#{arg}".to_sym
25
+ #end
26
+
27
+ Ripl.start :binding => @c.instance_eval{ binding }
28
+ #Ripl.start
29
+
30
+
31
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ # CLI for circonus data API
3
+
4
+ require 'rubygems'
5
+ require 'circonus'
6
+ require 'circonus/values'
7
+ require 'pp'
8
+ require 'ripl'
9
+
10
+ # You need to have thse in a ~/.circonus.rb file
11
+ #@username="username"
12
+ #@password="password"
13
+ #@account="myaccountname"
14
+
15
+ require "#{ENV['HOME']}/.circonus.rb"
16
+
17
+ @d = Circonus::Values.new(@username,@password,@account)
18
+ @d.login()
19
+
20
+ def help()
21
+ return methods.select {|s| s.to_s.match('(data|graph|value)') }.sort.join(' ')
22
+ end
23
+
24
+ Ripl.start :binding => @d.instance_eval{ binding }
25
+
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env ruby
2
+ # Add a single apache 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 apache for host #{host}\n"
58
+ data = {
59
+ :agent_id => agentid,
60
+ :target => host,
61
+ :module => "apache",
62
+ }
63
+ bundle = {
64
+ "type" => "http",
65
+ "target" => host,
66
+ "tags" => options[:tags],
67
+ "timeout" => 10,
68
+ "period" => 60,
69
+ "display_name" => "#{host} http:apache",
70
+ "brokers" => [
71
+ agentid
72
+ ],
73
+ "metrics" => [
74
+ ],
75
+ "config" => {
76
+ "code"=>"^200$",
77
+ "extract"=>"^([\\w\\s]+):\\s*(\\S{1,30})\\r?\\n",
78
+ "header_Host"=>host,
79
+ "http_version"=>"1.1",
80
+ "method"=>"GET",
81
+ "read_limit"=>"1048576",
82
+ "redirects"=>"0",
83
+ "url"=>"http://#{host}/server-status?auto"
84
+ }
85
+ }
86
+ %w{ code }.each do |metric|
87
+ bundle['metrics'] << {
88
+ 'type' => 'text',
89
+ 'name' => metric
90
+ }
91
+ end
92
+ %w{ code truncated tt_firstbyte BusyWorkers bytes duration tt_connect IdleWorkers }.each do |metric|
93
+ bundle['metrics'] << {
94
+ 'type' => 'numeric',
95
+ 'name' => metric
96
+ }
97
+ end
98
+
99
+ do_update_check_bundle(bundle)
100
+
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'circonus'
5
+ require 'optparse'
6
+ require 'pp'
7
+ require "#{ENV['HOME']}/.circonus.rb"
8
+
9
+ class CirconusUtility
10
+ attr_accessor :c, :args, :debug_flag, :template, :tags
11
+
12
+ def initialize(apitoken,appname)
13
+ @args = []
14
+ @c = Circonus.new(apitoken,appname,nil)
15
+ @debug_flag = true
16
+ @template = nil
17
+ @tags = []
18
+ options()
19
+ end
20
+ def debug(msg)
21
+ puts msg if @debug_flag
22
+ end
23
+ def options
24
+ options = {}
25
+ options[:tags] = []
26
+ OptionParser.new { |opts|
27
+ opts.banner = "Usage: #{File.basename($0)} [-h] argument [-t tag1,tag2,...]\n"
28
+ opts.on( '-h', '--help', "This usage menu") do
29
+ puts opts
30
+ exit
31
+ end
32
+ opts.on( '-t','--tags TAGLIST',"Apply comma separated list of tags" ) do |t|
33
+ options[:tags] += t.split(/,/)
34
+ end
35
+ }.parse!
36
+ @tags = options[:tags]
37
+ @args = ARGV
38
+ usage(-1) unless @args.any?
39
+ end
40
+ def usage(exitcode=nil)
41
+ print <<EOF
42
+ Usage: #{File.basename($0)} argument [-t tag1,tag2,... ]
43
+ -h,--help This usage menu
44
+ -t,--tags Comma separated list of tag names to apply (default is an empty list)
45
+ EOF
46
+ exit(exitcode) unless exitcode.nil?
47
+ end
48
+
49
+ def do_update_check_bundle
50
+ search_check_bundle = @c.list_check_bundle({'display_name' => @template['display_name']})
51
+ existing = false
52
+ if search_check_bundle.any? # already exists...
53
+ existing = true
54
+ r = @c.update_check_bundle(search_check_bundle.first['_cid'],@template)
55
+ else
56
+ r = @c.add_check_bundle(@template)
57
+ end
58
+ if not r.nil? then
59
+ #debug "Result: #{r.inspect}"
60
+ debug "Success (#{existing ? 'updating' : 'adding'} #{@template['display_name']})\n"
61
+ end
62
+ end
63
+
64
+ def update
65
+ do_update_check_bundle
66
+ end
67
+
68
+ end
69
+
70
+ def get_nameservers(target)
71
+ list = `dig +short -t ns #{target} @8.8.8.8` # use Google public dns to look it up
72
+ nameservers = list.split().map { |m| m.sub(/\.$/,'') }
73
+ unless $?.to_i == 0
74
+ puts "nameservers lookup failed: #{list}"
75
+ exit($?.to_i)
76
+ end
77
+ return nameservers
78
+ end
79
+
80
+ cu = CirconusUtility.new(@apitoken,@appname)
81
+ template = {
82
+ "brokers"=>["/broker/1"],
83
+ "config"=>{ "ctype"=>"IN", "query"=>"www.hostname.com", "rtype"=>"NS" },
84
+ "display_name"=>"DNS - www.hostname.com @mydns.dns.com",
85
+ "metrics"=>
86
+ [
87
+ {"name"=>"answer", "status"=>"active", "type"=>"text"},
88
+ {"name"=>"cname", "status"=>"active", "type"=>"numeric"},
89
+ {"name"=>"rtt", "status"=>"active", "type"=>"histogram"}
90
+ ],
91
+ "notes"=>nil,
92
+ "period"=>60,
93
+ "status"=>"active",
94
+ "tags"=>[],
95
+ "target"=>"mydns.dns.com",
96
+ "timeout"=>10,
97
+ "type"=>"dns"
98
+ }
99
+
100
+ cu.debug_flag = true
101
+ hostnames = cu.args
102
+ hostnames.each do |hostname|
103
+ nameservers = get_nameservers(hostname)
104
+ cu.debug "Updating nameserver monitors for hostname: #{hostname} nameservers: #{nameservers.join(',')}"
105
+ nameservers.each do |ns|
106
+ template['display_name'] = "DNS - #{hostname} @#{ns}"
107
+ template['target'] = ns
108
+ template['config']['query'] = hostname
109
+ template['tags'] = cu.tags
110
+ cu.template = template
111
+ #cu.debug "Template=#{template.inspect}"
112
+ cu.update
113
+ end
114
+ end
115
+
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Add an HTTP site check
4
+ #
5
+
6
+ require 'rubygems'
7
+ require 'optparse'
8
+ require 'circonus'
9
+ require "#{ENV['HOME']}/.circonus.rb"
10
+ @c = Circonus.new(@apitoken,@appname,@agent)
11
+
12
+ options = {}
13
+ options[:multi] = false
14
+ OptionParser.new { |opts|
15
+ opts.banner = "Usage: #{File.basename($0)} [-h] [-m] sitename URL"
16
+ opts.on( '-h', '--help', "This usage menu") do
17
+ puts opts
18
+ print "sitename = The site's hostname\n"
19
+ print "URL = The actual url to check on the site\n"
20
+ exit
21
+ end
22
+ opts.on( '-m','--multi',"Use multiple circonus brokers" ) do
23
+ options[:multi] = true
24
+ end
25
+ }.parse!
26
+
27
+
28
+ def usage()
29
+ print <<EOF
30
+ Usage: add_http_check.rb sitename URL
31
+ -h,--help This usage menu
32
+ -m,--multi Use multiple circonus brokers
33
+ EOF
34
+ end
35
+
36
+ sitename = ARGV[0]
37
+ url = ARGV[1]
38
+
39
+ circonus_brokers = @c.search_broker("circonus",'_type')
40
+ circonus_brokers = circonus_brokers.select {|a| a['_name'] != 'HTTPTrap'} # filter out http trap broker...
41
+ agentids = circonus_brokers.map { |m| m['_cid'] }
42
+ agentids = agentids[0,1] unless options[:multi]
43
+
44
+ bundle_stub = {
45
+ "brokers"=>[ ],
46
+ "display_name"=>nil,
47
+ "period"=>60,
48
+ "target"=>nil,
49
+ "timeout"=>10,
50
+ "type"=>"http",
51
+ "metrics"=> [
52
+ {"name"=>"body_match", "type"=>"text"},
53
+ {"name"=>"bytes", "type"=>"numeric"},
54
+ {"name"=>"code", "type"=>"text"},
55
+ {"name"=>"duration", "type"=>"numeric"},
56
+ {"name"=>"truncated", "type"=>"numeric"},
57
+ {"name"=>"tt_connect", "type"=>"numeric"},
58
+ {"name"=>"tt_firstbyte", "type"=>"numeric"}
59
+ ],
60
+ "config" => {
61
+ "url"=>nil,
62
+ "http_version"=>"1.1",
63
+ "header_Host"=>nil,
64
+ "read_limit"=>"1048576",
65
+ "method"=>"GET",
66
+ "code"=>"^200$",
67
+ "redirects"=>"0"
68
+ }
69
+ }
70
+
71
+ bundle = bundle_stub.clone
72
+ bundle['brokers'] = agentids
73
+ bundle['target'] = sitename
74
+ bundle['display_name'] = "#{sitename} http"
75
+ bundle['config']['url'] = url
76
+ bundle['config']['header_Host'] = sitename
77
+
78
+ search_bundles = @c.search_check_bundle(bundle['display_name'],'display_name')
79
+ if search_bundles.any? # already exists...
80
+ r = @c.update_check_bundle(search_bundles.first['_cid'],bundle)
81
+ else
82
+ r = @c.add_check_bundle(bundle)
83
+ end
84
+ if not r.nil? then
85
+ print "Success\n"
86
+ #pp r
87
+ end
88
+
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Add alerts for nginx based service
4
+ #
5
+ # -- David Nicklay
6
+ #
7
+
8
+ require 'rubygems'
9
+ require 'circonus'
10
+ require "#{ENV['HOME']}/.circonus.rb"
11
+ @c = Circonus.new(@apitoken,@appname,@agent)
12
+
13
+ if ((ARGV.length < 1) or ARGV[0].match('^-')) then
14
+ print "Usage: add_nginx_alerts.rb template_name [alertid]\n"
15
+ exit(-1)
16
+ end
17
+ template_name = ARGV[0]
18
+ alertid = ARGV[1]
19
+
20
+ agents = @c.list_broker
21
+ agentid = agents.select { |a| a['_name'] == @agent }.first['_cid']
22
+
23
+ datapoints = 'requests'
24
+
25
+ title = "#{template_name} - #{datapoint}"
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
+ exit
126
+ if graphid.nil? then
127
+ r = @c.add_graph(data)
128
+ else
129
+ r = @c.update_graph(graphid,data)
130
+ end
131
+ pp r
132
+