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,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
+