circonus 3.3.0 → 3.4.0

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.
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
-