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 +3 -61
- data/bin/circonus-delete-host +8 -25
- data/bin/circonus-list-checkbundle +33 -0
- data/bin/circonus-list-tags +4 -0
- data/lib/circonusutil.rb +4 -9
- metadata +5 -7
- data/bin/circonus-data-cli +0 -25
- data/bin/circonus_list_checkbundle +0 -49
- data/bin/circonus_list_tags +0 -28
- data/bin/composite_builder.rb +0 -148
- data/bin/update_all_composites.rb +0 -71
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
|
-
|
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
|
|
data/bin/circonus-delete-host
CHANGED
@@ -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 '
|
6
|
-
require 'circonus'
|
7
|
-
require 'optparse'
|
8
|
-
require "#{ENV['HOME']}/.circonus.rb"
|
5
|
+
require 'circonusutil'
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
}
|
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
|
+
|
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
|
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] =
|
44
|
-
@options[:appname] =
|
45
|
-
@options[: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.
|
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/
|
80
|
-
- bin/
|
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
|
data/bin/circonus-data-cli
DELETED
@@ -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
|
-
|
data/bin/circonus_list_tags
DELETED
@@ -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
|
-
|
data/bin/composite_builder.rb
DELETED
@@ -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
|
-
|