circonus 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/circonus-cli CHANGED
@@ -2,69 +2,11 @@
2
2
  # CLI for circonus API
3
3
  # Most things can be accessed with list_*, get_*, add_*
4
4
 
5
- require 'rubygems'
6
- require 'circonus'
7
- require 'pp'
8
- require 'optparse'
9
5
  require 'ripl'
10
-
11
- # You can optionally define these in a ~/.circonus.rb file as a shortcut
12
- # Any arguments passed will override them...
13
- #@agent="mytestbroker"
14
- #@apitoken="blahblahblah"
15
- #@appname="curl"
16
- #@apiserver="api.circonus.com"
17
-
18
- rbfile = "#{ENV['HOME']}/.circonus.rb"
19
- require rbfile if File.exist? rbfile
20
-
21
- options = {}
22
- options[:apiserver] = @apiserver || "api.circonus.com" # can be something else for Circonus inside product...
23
- options[:appname] = @appname || "curl"
24
- options[:apitoken] = @apitoken
25
- options[:agent] = @agent || 'Ashburn, VA, US'
26
- OptionParser.new { |opts|
27
- opts.banner = "Usage: #{File.basename($0)} [-h] hostname [-t tag1,tag2,...]\n"
28
- opts.on( '-h', '--help', "This usage menu") do
29
- puts opts
30
- exit
31
- end
32
- opts.on( '-a','--appname APPNAME',"Name of application to report to Circonus (default: curl)" ) do |t|
33
- options[:appname] = t
34
- end
35
- opts.on( '-g','--agent APPNAME',"Name of agent to use" ) do |t|
36
- options[:agent] = t
37
- end
38
- opts.on( '-s','--server APISERVER',"API server to use (default: api.circonus.com)" ) do |t|
39
- options[:apiserver] = t
40
- end
41
- opts.on( '-t','--token APITOKEN',"API token to use (required in either .circonus.rb or in args" ) do |t|
42
- options[:apitoken] = t
43
- end
44
- }.parse!
45
-
46
- def usage()
47
- print <<EOF
48
- Usage: #{File.basename($0)} hostname [-t APITOKEN] [-a APPNAME ] [-s APISERVER] [-g AGENT]
49
- -h,--help This usage menu
50
- -g,--agent AGENTNAME Name of agent to use (default: 'Ashburn, VA, US')
51
- -a,--appname APPNAME The name of the application as reported to Circonus (default: curl)
52
- -s,--server APISERVER The hostname of the API server to use (default: api.circonus.com)
53
- -t,--token APITOKEN The API token to use (required in either .circonus.rb or in args)
54
- EOF
55
- end
56
-
57
- if options[:apitoken].to_s.empty?
58
- usage()
59
- exit -1
60
- end
61
-
62
- @c = Circonus.new(options[:apitoken],options[:appname],options[:agent])
63
- @c.set_server(options[:apiserver])
64
-
6
+ require 'circonusutil'
7
+ cu = CirconusUtil.new()
65
8
  def help()
66
9
  return methods().select { |m| m.to_s.match('^(list|get|add|delete|update|search)_') }.sort.join(' ')
67
10
  end
68
-
69
- Ripl.start :binding => @c.instance_eval{ binding }
11
+ Ripl.start :binding => cu.circonus.instance_eval{ binding }
70
12
 
@@ -2,34 +2,17 @@
2
2
  # Delete a single host (and all associated check bundles, graphs, and rule sets)
3
3
  # Use FQDN tag to identify it.
4
4
 
5
- require 'rubygems'
6
- require 'circonus'
7
- require 'optparse'
8
- require "#{ENV['HOME']}/.circonus.rb"
5
+ require 'circonusutil'
9
6
 
10
- options = {}
11
- OptionParser.new { |opts|
12
- opts.banner = "Usage: #{File.basename($0)} [-h] hostname\n"
13
- opts.on( '-h', '--help', "This usage menu") do
7
+ cu = CirconusUtil.new() { |opts,options|
8
+ opts.banner = "Usage: #{File.basename($0)} hostname\n"
9
+ host = ARGV[0]
10
+ if host.nil? or host.empty? then
11
+ puts "Missing hostname!"
14
12
  puts opts
15
- exit
13
+ exit -1
16
14
  end
17
- }.parse!
18
-
19
- def usage()
20
- print <<EOF
21
- Usage: #{File.basename($0)} hostname
22
- -h,--help This usage menu
23
- EOF
24
- end
25
-
26
- host = ARGV[0]
27
- if host.nil? or host.empty? then
28
- usage()
29
- exit -1
30
- end
31
-
32
- @c = Circonus.new(@apitoken,@appname,@agent)
15
+ }
33
16
 
34
17
  print "Deleting monitoring for host #{host}\n"
35
18
  cbs = @c.list_check_bundle({'tags_has'=>"fqdn:#{host.downcase}"})
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'circonusutil'
4
+ cu = CirconusUtil.new() { |opts,options|
5
+ options[:filter] = []
6
+ options[:target] = nil
7
+ opts.banner = "Usage: #{File.basename($0)} [-h] [--filter tag1,tag2,...] [--type type] [--target target]\n"
8
+ opts.on( '--attribute ATTRIBUTE',"attribute to print" ) do |a|
9
+ options[:attribute] = a
10
+ end
11
+ opts.on( '--type TYPE',"check bundle type" ) do |t|
12
+ options[:type] = t
13
+ end
14
+ opts.on( '--target TARGET',"Filter by a given target name" ) do |t|
15
+ options[:target] = t
16
+ end
17
+ opts.on( '--filter TAGLIST',"Use comma separated list of tags for searching (takes the intersection)" ) do |t|
18
+ options[:filter] += t.split(/,/).sort.uniq
19
+ end
20
+ }
21
+
22
+ filter = {}
23
+ filter['tags_has']=cu.options[:filter] unless cu.options[:filter].empty?
24
+ filter['target']=cu.options[:target] unless cu.options[:target].nil?
25
+ filter['type']=cu.options[:type] unless cu.options[:type].nil?
26
+ checkbundles = cu.circonus.list_check_bundle(filter)
27
+
28
+ if cu.options[:attribute]
29
+ puts checkbundles.map { |m| m[cu.options[:attribute]] }.join("\n")
30
+ else
31
+ pp checkbundles
32
+ end
33
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'circonusutil'
3
+ cu = CirconusUtil.new
4
+ puts cu.circonus.list_check_bundle.map { |m| m['tags'] }.flatten.sort.uniq.join("\n")
data/lib/circonusutil.rb CHANGED
@@ -4,9 +4,6 @@ require 'optparse'
4
4
  class CirconusUtil
5
5
  attr_accessor :options
6
6
  attr_accessor :circonus
7
- def add_opts(&optblock)
8
- @addl_opts = optblock
9
- end
10
7
  def parse_opts()
11
8
  OptionParser.new { |opts|
12
9
  opts.banner = "Usage: #{File.basename($0)}\n"
@@ -20,7 +17,7 @@ class CirconusUtil
20
17
  opts.on( '-s','--server APISERVER',"API server to use (default: api.circonus.com)" ) do |t|
21
18
  @options[:apiserver] = t
22
19
  end
23
- opts.on( '-t','--token APITOKEN',"API token to use (required in either .circonus.rb or in args" ) do |t|
20
+ opts.on( '-t','--token APITOKEN',"API token to use (required)" ) do |t|
24
21
  @options[:apitoken] = t
25
22
  end
26
23
  unless @additional_opts.nil?
@@ -37,12 +34,10 @@ class CirconusUtil
37
34
  @circonus.set_server(@options[:apiserver])
38
35
  end
39
36
  def initialize(&addl_opts)
40
- rbfile = "#{ENV['HOME']}/.circonus.rb"
41
- require rbfile if File.exist? rbfile
42
37
  @options = {}
43
- @options[:apiserver] = @apiserver || "api.circonus.com" # can be something else for Circonus inside product...
44
- @options[:appname] = @appname || "curl"
45
- @options[:apitoken] = @apitoken
38
+ @options[:apiserver] = ENV['CIRCONUS_APISERVER'] || "api.circonus.com" # can be something else for Circonus inside product...
39
+ @options[:appname] = ENV['CIRCONUS_APPNAME'] || "curl"
40
+ @options[:apitoken] = ENV['CIRCONUS_APITOKEN']
46
41
  @additional_opts = addl_opts
47
42
  self.parse_opts
48
43
  self.connect
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: circonus
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -64,20 +64,18 @@ email: david-vv@nicklay.com
64
64
  executables:
65
65
  - circonus-add-composite
66
66
  - circonus-cli
67
- - circonus-data-cli
68
67
  - circonus-delete-host
68
+ - circonus-list-checkbundle
69
+ - circonus-list-tags
69
70
  extensions: []
70
71
  extra_rdoc_files: []
71
72
  files:
72
73
  - lib/circonusutil.rb
73
74
  - lib/circonus.rb
74
75
  - bin/circonus-delete-host
75
- - bin/update_all_composites.rb
76
- - bin/circonus_list_checkbundle
77
- - bin/circonus-data-cli
78
76
  - bin/circonus-add-composite
79
- - bin/circonus_list_tags
80
- - bin/composite_builder.rb
77
+ - bin/circonus-list-tags
78
+ - bin/circonus-list-checkbundle
81
79
  - bin/circonus-cli
82
80
  - examples/add_dns_monitor.rb
83
81
  - examples/add_snmp_node.rb
@@ -1,25 +0,0 @@
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
-
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'circonus'
5
- require 'optparse'
6
- require "#{ENV['HOME']}/.circonus.rb"
7
-
8
- options = {}
9
- options[:tags] = []
10
- OptionParser.new { |opts|
11
- opts.banner = "Usage: #{File.basename($0)} [-h] [-t tag1,tag2,...] [--type type] [--target target]\n"
12
- opts.on( '-h', '--help', "This usage menu") do
13
- puts opts
14
- exit
15
- end
16
- opts.on( '-a','--attribute ATTRIBUTE',"attribute to print" ) do |a|
17
- options[:attribute] = a
18
- end
19
- opts.on( '--type TYPE',"check bundle type" ) do |t|
20
- options[:type] = t
21
- end
22
- opts.on( '-t','--tags TAGLIST',"Use comma separated list of tags for searching (takes the intersection)" ) do |t|
23
- options[:tags] += t.split(/,/).sort.uniq
24
- end
25
- }.parse!
26
-
27
- def usage()
28
- print <<EOF
29
- Usage: #{File.basename($0)} -t tag1,tag2,... [-a attribute]
30
- -h,--help This usage menu
31
- -t,--tags Comma separated list of tag names to use
32
- --type Filter by check bundle type (e.g. nginx, statsd, apache, http, etc..)
33
- --target Filter by target name
34
- -a,--attribute attribute to print
35
- EOF
36
- end
37
-
38
- @c = Circonus.new(@apitoken,@appname,@agent)
39
- checkbundles = @c.list_check_bundle
40
- checkbundles = checkbundles.select { |s| (s['tags'].sort.uniq & options[:tags]) == options[:tags] } if options[:tags].any?
41
- checkbundles = checkbundles.select{ |s| s['type'] == options[:type] } if options[:type]
42
- checkbundles = checkbundles.select{ |s| s['target'] == options[:target] } if options[:target]
43
-
44
- if options[:attribute]
45
- puts checkbundles.map { |m| m[options[:attribute]] }.join("\n")
46
- else
47
- pp checkbundles
48
- end
49
-
@@ -1,28 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'circonus'
5
- require 'optparse'
6
- require "#{ENV['HOME']}/.circonus.rb"
7
-
8
-
9
- options = {}
10
- options[:tags] = []
11
- OptionParser.new { |opts|
12
- opts.banner = "Usage: #{File.basename($0)} [-h]\n"
13
- opts.on( '-h', '--help', "This usage menu") do
14
- puts opts
15
- exit
16
- end
17
- }.parse!
18
-
19
- def usage()
20
- print <<EOF
21
- Usage: #{File.basename($0)}
22
- -h,--help This usage menu
23
- EOF
24
- end
25
-
26
- @c = Circonus.new(@apitoken,@appname,@agent)
27
- puts @c.list_check_bundle.map { |m| m['tags'] }.flatten.sort.uniq.join("\n")
28
-
@@ -1,148 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # Create composites for all unique metric names on a set of check bundles
4
- # matching an intersection of a set of tags and a check bundle type
5
-
6
- # This creates a total (named the same as: metricname)
7
- # and an average (which is named as: metricname_avg)
8
-
9
- require 'rubygems'
10
- require 'circonus'
11
- require 'optparse'
12
- require "#{ENV['HOME']}/.circonus.rb"
13
-
14
-
15
- def do_update_check_bundle(data)
16
- search_check_bundle = @cached_list_check_bundle.select { |s| s['display_name'] == data['display_name'] }
17
- existing = false
18
- if search_check_bundle.any? # already exists...
19
- existing = true
20
- #pp search_check_bundle.first['_cid']
21
- #pp data
22
- r = @c.update_check_bundle(search_check_bundle.first['_cid'],data)
23
- else
24
- r = @c.add_check_bundle(data)
25
- end
26
- if not r.nil? then
27
- pp r
28
- print "Success (#{existing ? 'updating' : 'adding'} #{data['display_name']})\n"
29
- end
30
- end
31
-
32
-
33
- options = {}
34
- options[:tags] = []
35
- options[:automation_tags] = ["source:composite-builder"]
36
- options[:datatype] = 'counter'
37
- options[:consolidation] = 'sum'
38
- OptionParser.new { |opts|
39
- opts.banner = "Usage: #{File.basename($0)} [-h] [-t tag1,tag2,...]\n"
40
- opts.on( '-h', '--help', "This usage menu") do
41
- puts opts
42
- exit
43
- end
44
- opts.on( '--counter',"Counter" ) do
45
- options[:datatype] = 'counter'
46
- end
47
- opts.on( '--gauge',"Gauge" ) do
48
- options[:datatype] = 'average'
49
- end
50
- opts.on( '--average',"Average" ) do
51
- options[:consolidation] = 'average'
52
- end
53
- opts.on( '--sum',"Sum" ) do
54
- options[:consolidation] = 'sum'
55
- end
56
- opts.on( '--type TYPE',"Check bundle type" ) do |t|
57
- options[:checkbundletype] = t
58
- end
59
- opts.on( '--metric METRICNAME',"Metric name" ) do |m|
60
- options[:metric] = m
61
- end
62
- opts.on( '-t','--tags TAGLIST',"Use comma separated list of tags for searching (takes the union)" ) do |t|
63
- options[:tags] += t.split(/,/).sort.uniq
64
- # these batch of tags provide information for other automation tools to keep the formulas up to date:
65
- end
66
- }.parse!
67
-
68
- options[:automation_tags] << "datatype:#{options[:datatype]}"
69
- options[:automation_tags] << "type:#{options[:checkbundletype]}"
70
- options[:automation_tags] << "consolidation:#{options[:consolidation]}"
71
-
72
- def usage()
73
- print <<EOF
74
- Usage: #{File.basename($0)} -t tag1,tag2,... --type CHECKBUNDLETYPE
75
- -h,--help This usage menu
76
- -t,--tags Comma separated list of tag names to use
77
- -m,--metric METRIC Metric name
78
- --counter Set if the metric is a counter (default)
79
- --gauge Set if the metric is a gauge
80
- --sum Set if you want a sum (default)
81
- --average Set if you want an average
82
- --type check bundle type (snmp, nginx, etc.)
83
- EOF
84
- end
85
-
86
- raise "No tags given" unless options[:tags].any?
87
- raise "No type given" unless options[:checkbundletype]
88
- @c = Circonus.new(@apitoken,@appname,@agent)
89
-
90
- # the agent that will do composites for us:
91
- agentid = @c.list_broker({'_name'=>'composite'}).first['_cid']
92
-
93
- # Get a cached copy for later use (this part is slow)
94
- @cached_list_check_bundle = @c.list_check_bundle
95
-
96
- # checkbundles matching what we want:
97
- checkbundles = @cached_list_check_bundle.select { |s| ((s['tags'].sort.uniq & options[:tags]) == options[:tags]) and (s['type'] == options[:checkbundletype]) }
98
-
99
- # unique metric names:
100
- metrics = checkbundles.map { |m| m['metrics'].map { |mn| mn['name'] } }.flatten.sort.uniq
101
- if options[:metric]
102
- if not metrics.include? options[:metric]
103
- raise "No matching metric name (#{options[:metric]}) found in check bundle"
104
- else
105
- metrics = [options[:metric]]
106
- end
107
- end
108
-
109
- # checkids in the group:
110
- checkids = checkbundles.map { |m| m['_checks'] }.flatten.sort
111
-
112
- puts metrics.inspect
113
- metrics.each do |metric|
114
- formula = '(' + checkids.map { |cid| "metric:#{options[:datatype]}(#{cid.split('/').last}, \"#{metric}\", 60000)" }.join(" + ") + ')'
115
- bundle = {
116
- "brokers"=>[agentid],
117
- "config"=>{
118
- "formula"=>formula,
119
- "composite_metric_name"=>metric
120
- },
121
- "display_name"=>"Composite Sum: #{options[:tags].join(',')} - #{metric}",
122
- "metrics"=>[
123
- {"name"=>metric, "status"=>"active", "type"=>"numeric"}
124
- ],
125
- "notes"=>nil,
126
- "period"=>60,
127
- "status"=>"active",
128
- "tags"=>(options[:tags] + options[:automation_tags] + ["metric:#{metric}"]),
129
- "target"=>"composite",
130
- "timeout"=>10,
131
- "type"=>"composite"
132
- }
133
-
134
- if options[:consolidation] == 'sum'
135
- # Create total of metrics
136
- do_update_check_bundle(bundle)
137
- end
138
-
139
- # Get average of metrics
140
- bundle['config']['formula'] = "#{formula} / #{checkids.length}"
141
- bundle['config']['composite_metric_name'] = "#{metric}_avg"
142
- bundle['display_name']="Composite Avg: #{options[:tags].join(',')} - #{metric}"
143
- bundle['metrics'].first['name'] = "#{metric}_avg"
144
- if options[:consolidation] == 'average'
145
- do_update_check_bundle(bundle)
146
- end
147
- end
148
-
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Use tags on existing composites to automate the updating of formulas on them
4
- #
5
-
6
- require 'rubygems'
7
- require 'circonus'
8
- require 'optparse'
9
- require "#{ENV['HOME']}/.circonus.rb"
10
-
11
- def do_update_check_bundle(data)
12
- r = @c.update_check_bundle(data['_cid'],data)
13
- if not r.nil? then
14
- pp r
15
- print "Success updating #{data['display_name']})\n"
16
- end
17
- end
18
-
19
- @c = Circonus.new(@apitoken,@appname,@agent)
20
-
21
- # the agent that will do composites for us:
22
- agentid = @c.list_broker({'_name'=>'composite'}).first['_cid']
23
-
24
- # Get a cached copy for later use (this part is slow)
25
- @cached_list_check_bundle = @c.list_check_bundle()
26
-
27
- def get_tag_values(tags)
28
- Hash[tags.map { |e| e.split(':',2) }] # convert tag list to a hash (Note: this squashes duplicates)
29
- end
30
-
31
- # Generate the composite formula
32
- def generate_formula(checkids,consolidation,datatype,metric)
33
- formula = '(' + checkids.map { |cid| "metric:#{datatype}(#{cid.split('/').last}, \"#{metric}\", 60000)" }.join(" + ") + ')'
34
- if consolidation == 'average'
35
- formula = "#{formula} / #{checkids.length}"
36
- end
37
- formula
38
- end
39
-
40
- # Test to see if the composite needs updating
41
- def composite_update(composite,tags,select_tags)
42
- puts composite['display_name']
43
-
44
- # get list of check bundles given the set of tags and type
45
- cbs = @cached_list_check_bundle.select { |s| s['type'] == tags['type'] }
46
- select_tags.each do |tag|
47
- cbs = cbs.select { |s| s['tags'].include? tag }
48
- end
49
- checkids = cbs.map { |m| m['_checks'].first.split('/').last }.sort
50
-
51
- new_formula = generate_formula(checkids,tags['consolidation'],tags['datatype'],tags['metric'])
52
- if composite['config']['formula'] != new_formula
53
- composite['config']['formula'] = new_formula
54
- composite['config']['composite_metric_name'] = tags['metric']
55
- do_update_check_bundle(composite)
56
- end
57
- end
58
-
59
- automation_tags = %w{ consolidation datatype type source metric }
60
- composites = @cached_list_check_bundle.select { |s|
61
- s['tags'].include?('source:composite-builder') and (s['type'] == 'composite')
62
- }
63
- composites.each do |composite|
64
- select_tags = composite['tags'].select { |s| not (automation_tags.include? s.split(':').first) } # strip automation tags
65
- tags = get_tag_values(composite['tags'])
66
- next if tags['type'].nil? or tags['datatype'].nil? or tags['consolidation'].nil? or tags['metric'].nil?
67
- next if tags['type'].empty? or tags['datatype'].empty? or tags['consolidation'].empty? or tags['metric'].empty?
68
-
69
- composite_update(composite,tags,select_tags)
70
- end
71
-