wavefront-cli 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +16 -0
- data/.travis.yml +5 -5
- data/HISTORY.md +91 -0
- data/README.md +1 -2
- data/lib/wavefront-cli/alert.rb +1 -1
- data/lib/wavefront-cli/base.rb +1 -1
- data/lib/wavefront-cli/base_write.rb +1 -1
- data/lib/wavefront-cli/cloudintegration.rb +1 -1
- data/lib/wavefront-cli/commands/alert.rb +1 -1
- data/lib/wavefront-cli/commands/cloudintegration.rb +1 -1
- data/lib/wavefront-cli/commands/dashboard.rb +3 -3
- data/lib/wavefront-cli/commands/derivedmetric.rb +48 -0
- data/lib/wavefront-cli/commands/event.rb +1 -1
- data/lib/wavefront-cli/commands/integration.rb +1 -1
- data/lib/wavefront-cli/commands/link.rb +1 -1
- data/lib/wavefront-cli/commands/message.rb +1 -1
- data/lib/wavefront-cli/commands/metric.rb +1 -1
- data/lib/wavefront-cli/commands/notificant.rb +1 -1
- data/lib/wavefront-cli/commands/proxy.rb +1 -1
- data/lib/wavefront-cli/commands/query.rb +6 -4
- data/lib/wavefront-cli/commands/report.rb +1 -1
- data/lib/wavefront-cli/commands/savedsearch.rb +1 -1
- data/lib/wavefront-cli/commands/source.rb +1 -1
- data/lib/wavefront-cli/commands/user.rb +1 -1
- data/lib/wavefront-cli/commands/webhook.rb +1 -1
- data/lib/wavefront-cli/commands/window.rb +1 -1
- data/lib/wavefront-cli/commands/write.rb +1 -1
- data/lib/wavefront-cli/controller.rb +3 -3
- data/lib/wavefront-cli/dashboard.rb +1 -1
- data/lib/wavefront-cli/derivedmetric.rb +53 -0
- data/lib/wavefront-cli/display/alert.rb +1 -1
- data/lib/wavefront-cli/display/cloudintegration.rb +1 -1
- data/lib/wavefront-cli/display/dashboard.rb +1 -1
- data/lib/wavefront-cli/display/derivedmetric.rb +14 -0
- data/lib/wavefront-cli/display/event.rb +1 -1
- data/lib/wavefront-cli/display/externallink.rb +1 -1
- data/lib/wavefront-cli/display/integration.rb +1 -1
- data/lib/wavefront-cli/display/maintenancewindow.rb +1 -1
- data/lib/wavefront-cli/display/message.rb +1 -1
- data/lib/wavefront-cli/display/metric.rb +1 -1
- data/lib/wavefront-cli/display/notificant.rb +1 -1
- data/lib/wavefront-cli/display/printer/long.rb +1 -1
- data/lib/wavefront-cli/display/printer/sparkline.rb +54 -0
- data/lib/wavefront-cli/display/printer/terse.rb +1 -1
- data/lib/wavefront-cli/display/proxy.rb +1 -1
- data/lib/wavefront-cli/display/query.rb +30 -21
- data/lib/wavefront-cli/display/report.rb +1 -1
- data/lib/wavefront-cli/display/savedsearch.rb +1 -1
- data/lib/wavefront-cli/display/source.rb +1 -1
- data/lib/wavefront-cli/display/user.rb +1 -1
- data/lib/wavefront-cli/display/webhook.rb +1 -1
- data/lib/wavefront-cli/display/write.rb +1 -1
- data/lib/wavefront-cli/event.rb +1 -1
- data/lib/wavefront-cli/externallink.rb +1 -1
- data/lib/wavefront-cli/integration.rb +1 -1
- data/lib/wavefront-cli/maintenancewindow.rb +1 -1
- data/lib/wavefront-cli/message.rb +1 -1
- data/lib/wavefront-cli/metric.rb +1 -1
- data/lib/wavefront-cli/notificant.rb +1 -1
- data/lib/wavefront-cli/opt_handler.rb +1 -1
- data/lib/wavefront-cli/proxy.rb +1 -1
- data/lib/wavefront-cli/query.rb +1 -1
- data/lib/wavefront-cli/savedsearch.rb +1 -1
- data/lib/wavefront-cli/source.rb +1 -1
- data/lib/wavefront-cli/string.rb +13 -6
- data/lib/wavefront-cli/user.rb +1 -1
- data/lib/wavefront-cli/version.rb +1 -1
- data/lib/wavefront-cli/webhook.rb +1 -1
- data/spec/spec_helper.rb +16 -16
- data/spec/wavefront-cli/commands/alert_spec.rb +1 -1
- data/spec/wavefront-cli/commands/base_spec.rb +1 -1
- data/spec/wavefront-cli/commands/cloudintegration_spec.rb +1 -1
- data/spec/wavefront-cli/commands/dashboard_spec.rb +1 -1
- data/spec/wavefront-cli/commands/derivedmetric_spec.rb +16 -0
- data/spec/wavefront-cli/commands/event_spec.rb +1 -1
- data/spec/wavefront-cli/commands/link_spec.rb +1 -1
- data/spec/wavefront-cli/commands/message_spec.rb +1 -1
- data/spec/wavefront-cli/commands/metric_spec.rb +1 -1
- data/spec/wavefront-cli/commands/proxy_spec.rb +1 -1
- data/spec/wavefront-cli/commands/query_spec.rb +1 -1
- data/spec/wavefront-cli/commands/webhook_spec.rb +1 -1
- data/spec/wavefront-cli/commands/window_spec.rb +1 -1
- data/spec/wavefront-cli/commands/write_spec.rb +1 -1
- data/spec/wavefront-cli/derivedmetric_spec.rb +79 -0
- data/spec/wavefront-cli/display/base_spec.rb +1 -1
- data/spec/wavefront-cli/string_spec.rb +1 -1
- data/wavefront-cli.gemspec +1 -1
- metadata +17 -8
- data/lib/wavefront-cli/output/wavefront.tf +0 -257
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module WavefrontDisplay
|
4
|
+
#
|
5
|
+
# Format human-readable output for derived metric definitions.
|
6
|
+
#
|
7
|
+
class DerivedMetric < Base
|
8
|
+
def do_describe
|
9
|
+
readable_time(:created, :updated, :createdEpochMillis,
|
10
|
+
:updatedEpochMillis)
|
11
|
+
long_output
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# The Unicode characters which we use to make a sparkline
|
2
|
+
#
|
3
|
+
BLOCKS = [' ', "\u2581", "\u2582", "\u2583", "\u2585", "\u2586",
|
4
|
+
"\u2587", "\u2588"].freeze
|
5
|
+
|
6
|
+
# How long the sparkline should be
|
7
|
+
#
|
8
|
+
SPARK_WIDTH = TW - 20
|
9
|
+
|
10
|
+
# A class to create very simple single-row sparklines of a Wavefront
|
11
|
+
# result.
|
12
|
+
#
|
13
|
+
class WavefrontSparkline
|
14
|
+
attr_reader :sparkline
|
15
|
+
|
16
|
+
def initialize(series)
|
17
|
+
@sparkline = '>' + generate_sparkline(series) + '<'
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String] the block corresponding to the given value in
|
21
|
+
# the given range. The `rescue` clause handles occasions when
|
22
|
+
# Wavefront returns NaN as a value, or if the range is zero.
|
23
|
+
#
|
24
|
+
def sized_block(v, range)
|
25
|
+
BLOCKS[(v / range * (BLOCKS.length - 1)).floor]
|
26
|
+
rescue StandardError
|
27
|
+
BLOCKS.first
|
28
|
+
end
|
29
|
+
|
30
|
+
# A recursive function which repeatedly halves a data series until
|
31
|
+
# it fits inside SPARK_WIDTH characters. It does this by merging
|
32
|
+
# adjacent pairs and finding the mean. This is crude.
|
33
|
+
# @param vals [Array] a series of values to display
|
34
|
+
# @return [Array]
|
35
|
+
#
|
36
|
+
def make_fit(vals)
|
37
|
+
return vals if vals.size < SPARK_WIDTH
|
38
|
+
vals.<< vals.last if vals.size.odd?
|
39
|
+
ret = vals.each_slice(2).with_object([]) { |s, a| a.<< s.inject(:+) / 2 }
|
40
|
+
make_fit(ret)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param data [Array] a series of [time, value] data points
|
44
|
+
# @return [String] the sparkline itself
|
45
|
+
#
|
46
|
+
def generate_sparkline(data)
|
47
|
+
values = data.map { |_k, v| v }
|
48
|
+
max = values.max || 0
|
49
|
+
min = values.min || 0
|
50
|
+
v_range = max - min
|
51
|
+
values = make_fit(values)
|
52
|
+
values.map { |v| sized_block(v - min, v_range) }.join
|
53
|
+
end
|
54
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'printer/sparkline'
|
2
3
|
|
3
4
|
module WavefrontDisplay
|
4
5
|
#
|
@@ -6,29 +7,37 @@ module WavefrontDisplay
|
|
6
7
|
#
|
7
8
|
class Query < Base
|
8
9
|
def do_default
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
else
|
20
|
-
[]
|
21
|
-
end
|
22
|
-
|
23
|
-
new = { name: data.name,
|
24
|
-
query: data.query,
|
25
|
-
timeseries: ts,
|
26
|
-
events: events }
|
27
|
-
|
28
|
-
@data = new
|
10
|
+
d_obj = { name: data.name,
|
11
|
+
query: data.query,
|
12
|
+
timeseries: mk_timeseries(data),
|
13
|
+
events: mk_events(data) }
|
14
|
+
|
15
|
+
if data.key?(:warnings) && !options[:nowarn]
|
16
|
+
d_obj[:warnings] = data[:warnings]
|
17
|
+
end
|
18
|
+
|
19
|
+
@data = d_obj
|
29
20
|
long_output
|
30
21
|
end
|
31
22
|
|
23
|
+
def mk_timeseries(data)
|
24
|
+
return [] unless data.key?(:timeseries)
|
25
|
+
|
26
|
+
data[:timeseries].each do |s|
|
27
|
+
unless options[:nospark]
|
28
|
+
s[:sparkline] = WavefrontSparkline.new(s[:data]).sparkline
|
29
|
+
s.reorder!({label: nil, sparkline: nil})
|
30
|
+
end
|
31
|
+
|
32
|
+
s[:data] = humanize_series(s[:data])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def mk_events(data)
|
37
|
+
return [] unless data.key?(:events)
|
38
|
+
data[:events].map { |s| humanize_event(s) }
|
39
|
+
end
|
40
|
+
|
32
41
|
def do_run
|
33
42
|
do_default
|
34
43
|
end
|
data/lib/wavefront-cli/event.rb
CHANGED
data/lib/wavefront-cli/metric.rb
CHANGED
data/lib/wavefront-cli/proxy.rb
CHANGED
data/lib/wavefront-cli/query.rb
CHANGED
data/lib/wavefront-cli/source.rb
CHANGED
data/lib/wavefront-cli/string.rb
CHANGED
@@ -9,7 +9,7 @@ class String
|
|
9
9
|
#
|
10
10
|
def cmd_fold(tw = TW, indent = 10)
|
11
11
|
gsub(/(-\w) /, '\\1^').scan_line(tw - 12).join("\n" + ' ' * indent)
|
12
|
-
.
|
12
|
+
.restored
|
13
13
|
end
|
14
14
|
|
15
15
|
# Wrapper around #fold()
|
@@ -24,8 +24,8 @@ class String
|
|
24
24
|
|
25
25
|
# Fold long lines with a hanging indent. Originally a special case
|
26
26
|
# for option folding, now addded the prefix parameter to make it
|
27
|
-
# more general.
|
28
|
-
#
|
27
|
+
# more general. Don't line-break default values, because it also
|
28
|
+
# breaks docopt.
|
29
29
|
#
|
30
30
|
# @param tw [Integer] terminal width
|
31
31
|
# @param indent [Integer] size of hanging indent, in chars
|
@@ -33,16 +33,23 @@ class String
|
|
33
33
|
# @return [String] the folded line
|
34
34
|
#
|
35
35
|
def fold(tw = TW, indent = 10, prefix = '')
|
36
|
-
chunks = scan_line(tw - 8)
|
36
|
+
chunks = gsub(/default: /, 'default:^').scan_line(tw - 8)
|
37
37
|
first_line = format("%s%s\n", prefix, chunks.shift)
|
38
38
|
|
39
|
-
return first_line if chunks.empty?
|
39
|
+
return first_line.restored if chunks.empty?
|
40
40
|
|
41
41
|
rest = chunks.join(' ').scan_line(tw - indent - 5).map do |l|
|
42
42
|
prefix + ' ' * indent + l
|
43
43
|
end
|
44
44
|
|
45
|
-
first_line + rest.join("\n") + "\n"
|
45
|
+
(first_line + rest.join("\n") + "\n").restored
|
46
|
+
end
|
47
|
+
|
48
|
+
# We use a carat as a temporary whitespace character to avoid
|
49
|
+
# undesirable line breaking. This puts it back
|
50
|
+
#
|
51
|
+
def restored
|
52
|
+
tr('^', ' ')
|
46
53
|
end
|
47
54
|
|
48
55
|
# @param width [Integer] length of longest string (width of
|
data/lib/wavefront-cli/user.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
WF_CLI_VERSION = '2.
|
1
|
+
WF_CLI_VERSION = '2.5.0'.freeze
|
data/spec/spec_helper.rb
CHANGED
@@ -162,27 +162,27 @@ def list_tests(cmd, pth = nil, k = nil)
|
|
162
162
|
k)
|
163
163
|
end
|
164
164
|
|
165
|
-
def tag_tests(cmd, id, bad_id, pth = nil)
|
165
|
+
def tag_tests(cmd, id, bad_id, pth = nil, k = nil)
|
166
166
|
pth ||= cmd
|
167
|
-
cmd_to_call(cmd, "tags #{id}", path: "/api/v2/#{pth}/#{id}/tag")
|
167
|
+
cmd_to_call(cmd, "tags #{id}", { path: "/api/v2/#{pth}/#{id}/tag" }, k)
|
168
168
|
cmd_to_call(cmd, "tag set #{id} mytag",
|
169
|
-
method: :post,
|
170
|
-
|
171
|
-
|
172
|
-
|
169
|
+
{ method: :post,
|
170
|
+
path: "/api/v2/#{pth}/#{id}/tag",
|
171
|
+
body: %w[mytag].to_json,
|
172
|
+
headers: JSON_POST_HEADERS }, k)
|
173
173
|
cmd_to_call(cmd, "tag set #{id} mytag1 mytag2",
|
174
|
-
method: :post,
|
175
|
-
|
176
|
-
|
177
|
-
|
174
|
+
{ method: :post,
|
175
|
+
path: "/api/v2/#{pth}/#{id}/tag",
|
176
|
+
body: %w[mytag1 mytag2].to_json,
|
177
|
+
headers: JSON_POST_HEADERS }, k)
|
178
178
|
cmd_to_call(cmd, "tag add #{id} mytag",
|
179
|
-
method: :put, path: "/api/v2/#{pth}/#{id}/tag/mytag")
|
179
|
+
{ method: :put, path: "/api/v2/#{pth}/#{id}/tag/mytag" }, k)
|
180
180
|
cmd_to_call(cmd, "tag delete #{id} mytag",
|
181
|
-
method: :delete, path: "/api/v2/#{pth}/#{id}/tag/mytag")
|
182
|
-
cmd_to_call(cmd, "tag clear #{id}", method: :post,
|
183
|
-
|
184
|
-
|
185
|
-
|
181
|
+
{ method: :delete, path: "/api/v2/#{pth}/#{id}/tag/mytag" }, k)
|
182
|
+
cmd_to_call(cmd, "tag clear #{id}", { method: :post,
|
183
|
+
path: "/api/v2/#{pth}/#{id}/tag",
|
184
|
+
body: [].to_json,
|
185
|
+
headers: JSON_POST_HEADERS }, k)
|
186
186
|
invalid_ids(cmd, ["tags #{bad_id}", "tag clear #{bad_id}",
|
187
187
|
"tag add #{bad_id} mytag", "tag delete #{bad_id} mytag"])
|
188
188
|
invalid_tags(cmd, ["tag add #{id} #{BAD_TAG}", "tag delete #{id} #{BAD_TAG}"])
|