wavefront-client 3.0.0 → 3.1.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.
- checksums.yaml +8 -8
- data/README.md +57 -6
- data/bin/wavefront +54 -12
- data/lib/wavefront/cli/alerts.rb +92 -12
- data/lib/wavefront/cli/ts.rb +22 -10
- data/lib/wavefront/cli.rb +22 -2
- data/lib/wavefront/client/version.rb +1 -1
- data/lib/wavefront/client.rb +1 -2
- data/lib/wavefront/constants.rb +4 -2
- data/lib/wavefront/response.rb +37 -4
- data/wavefront-client.gemspec +2 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjE5OWM5OWIyYjcxNWI2MGJjNGRiOWI1YjBlMjI1OWFiMzIyMWVjYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OGJkZTg1ZTgwMDdjMmZhZDhiYjIyZDVlYmJlYzMzNGZiZDI4ZWEyOQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTBhNmI4OWJmOWJlM2I2NDMwYTNhNjIzMGNjZjM0OWVlMjdjMzU1YWUwNjYy
|
10
|
+
MTZjYjIwYjI2MDhlNDU3ZmJjYmZjODk1NmY0ZTM0OGJlMzMzMDJjZmNjN2Jk
|
11
|
+
MDk4N2MxODQzYzQ0MDQxMzRkY2Y2YzMwOWE3ODA3ZGFjZDA2MGM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YjJhOGNmOTEyYzE1ZmRlN2JhMjNkMTgwMmVmOGU2YWJhYjY2MGRjMGVmNTFm
|
14
|
+
YjQwZmJhMTRhYTBhYWRmM2ViNGIyZjlhYTQ5Y2JiYzIxOTMyZTQyZDUxNTdl
|
15
|
+
MGNlMWVhMjNlNjkzM2U2MjAwNjdmY2QxYzgyOWExZGQyYTc2ZDE=
|
data/README.md
CHANGED
@@ -180,16 +180,18 @@ See `<command> --help` for more information on a specific command.
|
|
180
180
|
|
181
181
|
$ wavefront ts --help
|
182
182
|
Usage: wavefront COMMAND QUERY (OPTIONS)
|
183
|
-
-
|
183
|
+
-c, --config path to configuration file (default: ${HOME}/.wavefront)
|
184
|
+
-P, --profile profile in configuration file (default: default)
|
184
185
|
-D, --debug Enable debug mode
|
186
|
+
-S, --seconds Query granularity of seconds
|
185
187
|
-m, --minutes Query granularity of minutes
|
186
188
|
-H, --hours Query granularity of hours
|
187
|
-
-
|
188
|
-
-
|
189
|
-
-
|
189
|
+
-d, --days Query granularity of days
|
190
|
+
-s, --start start of query window in epoch seconds or parseable format
|
191
|
+
-e, --end end of query window in epoch seconds or parseable format
|
190
192
|
-t, --token Wavefront authentication token
|
191
|
-
-
|
192
|
-
-f, --format Output format (raw, ruby, graphite, highcharts) (default: raw)
|
193
|
+
-E, --endpoint Connect to alternative cluster endpoint (default: metrics.wavefront.com)
|
194
|
+
-f, --format Output format (raw, ruby, graphite, highcharts, human) (default: raw)
|
193
195
|
-p, --prefixlength The number of path elements to treat as a prefix when doing schema manipulations (default: 1)
|
194
196
|
-X, --strict Flag to not return points outside the query window [q;s) (default: true)
|
195
197
|
-O, --includeObsoleteMetrics Flag to include metrics that have not been reporting for more than 4 weeks,defaults to false
|
@@ -213,6 +215,55 @@ $ wavefront alerts snoozed -t TOKEN -f json --shared ops
|
|
213
215
|
...
|
214
216
|
```
|
215
217
|
|
218
|
+
#### Notes on Options
|
219
|
+
|
220
|
+
##### Times
|
221
|
+
|
222
|
+
The query window can be defined by using Unix epoch times (as shown
|
223
|
+
by `date "%+s"`) or by entering any Ruby `strptime`-parseable string.
|
224
|
+
For instance:
|
225
|
+
|
226
|
+
```bash
|
227
|
+
$ wavefront --start 12:15 --end 12:20 ...
|
228
|
+
```
|
229
|
+
|
230
|
+
will request data points between 12:15 and 12:20pm today. If you ran
|
231
|
+
that in the morning, the time would be invalid, and you would get a
|
232
|
+
400 error from Wavefront, so something of the form
|
233
|
+
`2016-04-17T12:25:00` would remove all ambiguity.
|
234
|
+
|
235
|
+
There is no need to include a timezone in your parseable string: the
|
236
|
+
`wavefront` CLI will automatically use your local timezone when it
|
237
|
+
parses the string.
|
238
|
+
|
239
|
+
#### Default Configuration
|
240
|
+
|
241
|
+
Passing tokens and endpoints into the `wavefront` command can become
|
242
|
+
tiresome, so you can put such data into an `ini`-style configuration
|
243
|
+
file. By default this file should be located at `${HOME}/.wavefront`,
|
244
|
+
though you can override the location with the `-c` flag.
|
245
|
+
|
246
|
+
You can switch between Wavefront accounts using profile stanzas,
|
247
|
+
selected with the `-P` option. If `-P` is not supplied, the
|
248
|
+
`default` profile will be used. Not having a useable configuration
|
249
|
+
file will not cause an error.
|
250
|
+
|
251
|
+
A configuration file looks like this:
|
252
|
+
|
253
|
+
```
|
254
|
+
[default]
|
255
|
+
token = abcdefab-1234-abcd-1234-abcdefabcdef
|
256
|
+
endpoint = companya.wavefront.com
|
257
|
+
format = human
|
258
|
+
|
259
|
+
[companyb]
|
260
|
+
token = 12345678-abcd-0123-abcd-123456789abc
|
261
|
+
endpoint = metrics.wavefront.com
|
262
|
+
```
|
263
|
+
|
264
|
+
The key for each key-value pair can match any long option show in the
|
265
|
+
command `help`, so you can set, for instance, a default output
|
266
|
+
format, as shown above.
|
216
267
|
|
217
268
|
## Building and installing
|
218
269
|
|
data/bin/wavefront
CHANGED
@@ -12,52 +12,94 @@
|
|
12
12
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
|
-
|
15
|
+
#
|
16
16
|
require 'wavefront/client'
|
17
17
|
require 'slop'
|
18
|
+
require 'pathname'
|
19
|
+
require 'wavefront/cli'
|
18
20
|
|
21
|
+
begin
|
19
22
|
options = Slop.parse(strict: true) do
|
20
23
|
banner 'Usage: wavefront COMMAND QUERY (OPTIONS)'
|
21
24
|
on 'h', 'help', 'Display this message'
|
22
25
|
|
26
|
+
command :version do
|
27
|
+
description 'Display the client version and exit'
|
28
|
+
run do
|
29
|
+
puts Wavefront::Client::VERSION
|
30
|
+
exit 0
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
23
34
|
command 'ts' do
|
24
35
|
description "Query the timeseries"
|
25
|
-
on '
|
36
|
+
on 'c', 'config=', 'path to configuration file', default:
|
37
|
+
Pathname.new(ENV['HOME']) + '.wavefront'
|
38
|
+
on 'P', 'profile=', 'profile in configuration file', default: 'default'
|
26
39
|
on 'D', 'debug', 'Enable debug mode'
|
40
|
+
on 'S', 'seconds', 'Query granularity of seconds'
|
27
41
|
on 'm', 'minutes', 'Query granularity of minutes'
|
28
42
|
on 'H', 'hours', 'Query granularity of hours'
|
29
|
-
on '
|
30
|
-
on '
|
31
|
-
on '
|
43
|
+
on 'd', 'days', 'Query granularity of days'
|
44
|
+
on 's', 'start=', 'start of query window in epoch seconds or parseable format'
|
45
|
+
on 'e', 'end=', 'end of query window in epoch seconds or parseable format'
|
32
46
|
on 't', 'token=', 'Wavefront authentication token'
|
33
|
-
on '
|
47
|
+
on 'E', 'endpoint=', 'Connect to alternative cluster endpoint', default: Wavefront::Client::DEFAULT_HOST.to_s
|
34
48
|
on 'f', 'format=', "Output format (#{Wavefront::Client::FORMATS.join(', ')})", default: Wavefront::Client::DEFAULT_FORMAT.to_s
|
35
|
-
on 'p', 'prefixlength=', '
|
49
|
+
on 'p', 'prefixlength=', 'Number of path elements to treat as a prefix in schema manipulation', default: Wavefront::Client::DEFAULT_PREFIX_LENGTH
|
36
50
|
on 'X', 'strict=','Flag to not return points outside the query window [q;s) ', default: Wavefront::Client::DEFAULT_STRICT
|
37
|
-
on 'O', 'includeObsoleteMetrics=', '
|
51
|
+
on 'O', 'includeObsoleteMetrics=', 'Include metrics which have not reported for > 4 weeks', default: Wavefront::Client::DEFAULT_OBSOLETE_METRICS
|
38
52
|
on 'h', 'help', 'Display this message'
|
39
53
|
run do |options, arguments|
|
54
|
+
pf_opts = Wavefront::Cli.new(options, arguments).load_profile || {}
|
40
55
|
require 'wavefront/cli/ts'
|
41
|
-
cli = Wavefront::Cli::Ts.new(options, arguments)
|
42
|
-
|
56
|
+
cli = Wavefront::Cli::Ts.new(options.to_hash.merge(pf_opts), arguments)
|
57
|
+
begin
|
58
|
+
cli.run
|
59
|
+
rescue => e
|
60
|
+
puts 'Timeseries query failed.'
|
61
|
+
puts e
|
62
|
+
exit 1
|
63
|
+
end
|
43
64
|
end
|
44
65
|
end
|
45
66
|
|
46
67
|
command 'alerts' do
|
68
|
+
banner 'Usage: wavefront alerts (OPTIONS) ALERT_STATE'
|
47
69
|
description "Query alerts"
|
70
|
+
on 'c', 'config=', 'path to configuration file', default:
|
71
|
+
Pathname.new(ENV['HOME']) + '.wavefront'
|
72
|
+
on 'P', 'profile=', 'profile in configuration file', default: 'default'
|
48
73
|
on 'E', 'endpoint=', 'Connect to alternative cluster endpoint', default: Wavefront::Client::DEFAULT_HOST.to_s
|
49
74
|
on 'f', 'format=', 'Output format (ruby, json)', default: 'ruby'
|
75
|
+
on 'f', 'format=', "Output format (#{Wavefront::Client::ALERT_FORMATS.join(', ')})", default: Wavefront::Client::DEFAULT_ALERT_FORMAT.to_s
|
50
76
|
on 'h', 'help', 'Display this message'
|
51
77
|
on 'p', 'private=', 'Retrieve only alerts with named private tags, comma delimited.'
|
52
78
|
on 's', 'shared=', 'Retrieve only alerts with named shared tags, comma delimited.'
|
53
79
|
on 't', 'token=', 'Wavefront authentication token'
|
54
80
|
run do |options, arguments|
|
81
|
+
pf_opts = Wavefront::Cli.new(options, arguments).load_profile || {}
|
55
82
|
require 'wavefront/cli/alerts'
|
56
|
-
cli = Wavefront::Cli::Alerts.new(options,
|
57
|
-
|
83
|
+
cli = Wavefront::Cli::Alerts.new(options.to_hash.merge(pf_opts),
|
84
|
+
arguments)
|
85
|
+
begin
|
86
|
+
cli.run
|
87
|
+
rescue => e
|
88
|
+
puts 'Alert query failed.'
|
89
|
+
puts e
|
90
|
+
exit 1
|
91
|
+
end
|
58
92
|
end
|
59
93
|
end
|
60
94
|
|
95
|
+
|
96
|
+
end
|
97
|
+
rescue Slop::InvalidOptionError => e
|
98
|
+
puts 'invalid option error: '+ e.to_s
|
99
|
+
exit 1
|
100
|
+
rescue Slop::MissingArgumentError => e
|
101
|
+
puts 'option parsing error: '+ e.to_s
|
102
|
+
exit 1
|
61
103
|
end
|
62
104
|
|
63
105
|
puts options
|
data/lib/wavefront/cli/alerts.rb
CHANGED
@@ -17,6 +17,7 @@ require 'wavefront/alerting'
|
|
17
17
|
require 'wavefront/cli'
|
18
18
|
require 'json'
|
19
19
|
require 'pp'
|
20
|
+
require 'time'
|
20
21
|
|
21
22
|
class Wavefront::Cli::Alerts < Wavefront::Cli
|
22
23
|
|
@@ -26,12 +27,18 @@ class Wavefront::Cli::Alerts < Wavefront::Cli
|
|
26
27
|
alerts = Wavefront::Alerting.new(@options[:token])
|
27
28
|
queries = alerts.public_methods(false).sort
|
28
29
|
queries.delete(:token)
|
29
|
-
|
30
|
-
if arguments
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
|
31
|
+
raise 'Missing query.' if arguments.empty?
|
32
|
+
query = arguments[0].to_sym
|
33
|
+
|
34
|
+
unless queries.include?(query)
|
35
|
+
raise 'State must be one of: ' + queries.each {|q| q.to_s}.join(', ')
|
36
|
+
end
|
37
|
+
|
38
|
+
unless Wavefront::Client::ALERT_FORMATS.include?(
|
39
|
+
@options[:format].to_sym)
|
40
|
+
raise 'Output format must be one of: ' +
|
41
|
+
Wavefront::Client::ALERT_FORMATS.join(', ')
|
35
42
|
end
|
36
43
|
|
37
44
|
# This isn't especially nice, but if require to
|
@@ -42,22 +49,20 @@ class Wavefront::Cli::Alerts < Wavefront::Cli
|
|
42
49
|
if @options[:shared]
|
43
50
|
options[:shared_tags] = @options[:shared].delete(' ').split(',')
|
44
51
|
end
|
52
|
+
|
45
53
|
if @options[:private]
|
46
54
|
options[:private_tags] = @options[:private].delete(' ').split(',')
|
47
55
|
end
|
48
56
|
|
49
|
-
|
50
|
-
result = alerts.send(query, options)
|
51
|
-
else
|
52
|
-
puts "Your query should be one of: #{ queries.each {|q| q.to_s}.join(', ') }. See --help for more information"
|
53
|
-
exit 1
|
54
|
-
end
|
57
|
+
result = alerts.send(query, options)
|
55
58
|
|
56
59
|
case @options[:format].to_sym
|
57
60
|
when :ruby
|
58
61
|
pp result
|
59
62
|
when :json
|
60
63
|
puts JSON.pretty_generate(JSON.parse(result))
|
64
|
+
when :human
|
65
|
+
puts humanize(JSON.parse(result))
|
61
66
|
else
|
62
67
|
puts "Invalid output format, See --help for more detail."
|
63
68
|
exit 1
|
@@ -65,4 +70,79 @@ class Wavefront::Cli::Alerts < Wavefront::Cli
|
|
65
70
|
|
66
71
|
exit 0
|
67
72
|
end
|
73
|
+
|
74
|
+
def humanize(alerts)
|
75
|
+
#
|
76
|
+
# Selectively display alert information in an easily
|
77
|
+
# human-readable format. I have chosen not to display certain
|
78
|
+
# fields which I don't think are useful in this context. I also
|
79
|
+
# wish to put the fields in order. Here are the fields I want, in
|
80
|
+
# the order I want them.
|
81
|
+
#
|
82
|
+
row_order = %w(name created severity condition displayExpression
|
83
|
+
minutes resolveAfterMinutes updated alertStates
|
84
|
+
metricsUsed hostsUsed additionalInformation)
|
85
|
+
|
86
|
+
# build up an array of lines then turn it into a string and
|
87
|
+
# return it
|
88
|
+
#
|
89
|
+
# Most things get printed with the human_line() method, but some
|
90
|
+
# data needs special handling. To do that, just add a method
|
91
|
+
# called human_line_key() where key is something in row_order,
|
92
|
+
# and it will be found.
|
93
|
+
#
|
94
|
+
x = alerts.map do |alert|
|
95
|
+
row_order.map do |key|
|
96
|
+
lm = "human_line_#{key}"
|
97
|
+
if self.respond_to?(lm)
|
98
|
+
self.method(lm.to_sym).call(key, alert[key])
|
99
|
+
else
|
100
|
+
human_line(key, alert[key])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def human_line(k, v)
|
107
|
+
'%-22s%s' % [k, v]
|
108
|
+
end
|
109
|
+
|
110
|
+
def human_line_created(k, v)
|
111
|
+
#
|
112
|
+
# The 'created' and 'updated' timestamps are in epoch
|
113
|
+
# milliseconds
|
114
|
+
#
|
115
|
+
human_line(k, Time.at(v / 1000))
|
116
|
+
end
|
117
|
+
|
118
|
+
def human_line_updated(k, v)
|
119
|
+
human_line_created(k, v)
|
120
|
+
end
|
121
|
+
|
122
|
+
def human_line_hostsUsed(k, v)
|
123
|
+
#
|
124
|
+
# Put each host on its own line, indented.
|
125
|
+
#
|
126
|
+
v.sort!
|
127
|
+
[human_line(k, v.shift)] + v.map {|el| human_line('', el)}
|
128
|
+
end
|
129
|
+
|
130
|
+
def human_line_metricsUsed(k, v)
|
131
|
+
human_line_hostsUsed(k, v)
|
132
|
+
end
|
133
|
+
|
134
|
+
def human_line_alertStates(k, v)
|
135
|
+
human_line(k, v.join(','))
|
136
|
+
end
|
137
|
+
|
138
|
+
def human_line_additionalInformation(k, v)
|
139
|
+
human_line(k, indent_wrap(v))
|
140
|
+
end
|
141
|
+
|
142
|
+
def indent_wrap(line, cols=78, offset=22)
|
143
|
+
#
|
144
|
+
# hanging indent long lines to fit in an 80-column terminal
|
145
|
+
#
|
146
|
+
line.gsub(/(.{1,#{cols - offset}})(\s+|\Z)/, "\\1\n#{' ' * offset}")
|
147
|
+
end
|
68
148
|
end
|
data/lib/wavefront/cli/ts.rb
CHANGED
@@ -17,29 +17,39 @@ require 'wavefront/client'
|
|
17
17
|
require 'wavefront/cli'
|
18
18
|
require 'pp'
|
19
19
|
require 'json'
|
20
|
+
require 'date'
|
20
21
|
|
21
22
|
class Wavefront::Cli::Ts < Wavefront::Cli
|
22
23
|
|
23
24
|
attr_accessor :options, :arguments
|
24
25
|
|
26
|
+
def parse_time(t)
|
27
|
+
return Time.at(t.to_i) if t.match(/^\d+$/)
|
28
|
+
begin
|
29
|
+
return DateTime.parse("#{t} #{Time.now.getlocal.zone}").to_time.utc
|
30
|
+
rescue
|
31
|
+
raise "cannot parse timestamp '#{t}'."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
25
35
|
def run
|
36
|
+
raise 'Please supply a query.' if @arguments.empty?
|
26
37
|
query = @arguments[0]
|
27
|
-
|
38
|
+
|
39
|
+
if @options[:minutes]
|
28
40
|
granularity = 'm'
|
29
|
-
elsif @options
|
41
|
+
elsif @options[:hours]
|
30
42
|
granularity = 'h'
|
31
|
-
elsif @options
|
43
|
+
elsif @options[:seconds]
|
32
44
|
granularity = 's'
|
33
|
-
elsif @options
|
45
|
+
elsif @options[:days]
|
34
46
|
granularity = 'd'
|
35
47
|
else
|
36
|
-
|
37
|
-
exit 1
|
48
|
+
raise "You must specify a granularity of either --seconds, --minutes --hours or --days. See --help for more information."
|
38
49
|
end
|
39
50
|
|
40
51
|
unless Wavefront::Client::FORMATS.include?(@options[:format].to_sym)
|
41
|
-
|
42
|
-
exit 1
|
52
|
+
raise "The output format must be one of: #{Wavefront::Client::FORMATS.join(', ')}."
|
43
53
|
end
|
44
54
|
|
45
55
|
options = Hash.new
|
@@ -47,11 +57,11 @@ class Wavefront::Cli::Ts < Wavefront::Cli
|
|
47
57
|
options[:prefix_length] = @options[:prefixlength].to_i
|
48
58
|
|
49
59
|
if @options[:start]
|
50
|
-
options[:start_time] =
|
60
|
+
options[:start_time] = parse_time(@options[:start])
|
51
61
|
end
|
52
62
|
|
53
63
|
if @options[:end]
|
54
|
-
options[:end_time] =
|
64
|
+
options[:end_time] = parse_time(@options[:end])
|
55
65
|
end
|
56
66
|
|
57
67
|
wave = Wavefront::Client.new(@options[:token], @options[:endpoint], @options[:debug])
|
@@ -60,6 +70,8 @@ class Wavefront::Cli::Ts < Wavefront::Cli
|
|
60
70
|
puts wave.query(query, granularity, options)
|
61
71
|
when :graphite
|
62
72
|
puts wave.query(query, granularity, options).graphite.to_json
|
73
|
+
when :human
|
74
|
+
puts wave.query(query, granularity, options).human
|
63
75
|
else
|
64
76
|
pp wave.query(query, granularity, options)
|
65
77
|
end
|
data/lib/wavefront/cli.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
Copyright 2015 Wavefront Inc.
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
you may not use this file except in compliance with the License.
|
@@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
|
|
14
14
|
|
15
15
|
=end
|
16
16
|
|
17
|
+
require 'inifile'
|
18
|
+
|
17
19
|
module Wavefront
|
18
20
|
class Cli
|
19
21
|
|
@@ -23,11 +25,29 @@ module Wavefront
|
|
23
25
|
@options = options
|
24
26
|
@arguments = arguments
|
25
27
|
|
26
|
-
if @options
|
28
|
+
if @options[:help]
|
27
29
|
puts @options
|
28
30
|
exit 0
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
34
|
+
def load_profile
|
35
|
+
cf = Pathname.new(options[:config])
|
36
|
+
pf = options[:profile]
|
37
|
+
|
38
|
+
if cf.exist?
|
39
|
+
raw = IniFile.load(cf)
|
40
|
+
profile = raw[pf]
|
41
|
+
|
42
|
+
unless profile.empty?
|
43
|
+
puts "using #{pf} profile from #{cf}" if options[:debug]
|
44
|
+
return profile.inject({}){|x, (k, v)| x[k.to_sym] = v; x }
|
45
|
+
end
|
46
|
+
|
47
|
+
else
|
48
|
+
puts "no config file at '#{cf}': using options" if options[:debug]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
32
52
|
end
|
33
53
|
end
|
data/lib/wavefront/client.rb
CHANGED
@@ -38,7 +38,7 @@ module Wavefront
|
|
38
38
|
|
39
39
|
def query(query, granularity='m', options={})
|
40
40
|
|
41
|
-
options[:end_time] ||= Time.now
|
41
|
+
options[:end_time] ||= Time.now.utc
|
42
42
|
options[:start_time] ||= options[:end_time] - DEFAULT_PERIOD_SECONDS
|
43
43
|
options[:response_format] ||= DEFAULT_FORMAT
|
44
44
|
options[:prefix_length] ||= DEFAULT_PREFIX_LENGTH
|
@@ -76,6 +76,5 @@ module Wavefront
|
|
76
76
|
RestClient.log = 'stdout'
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
80
79
|
end
|
81
80
|
end
|
data/lib/wavefront/constants.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
Copyright 2015 Wavefront Inc.
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
you may not use this file except in compliance with the License.
|
@@ -22,7 +22,9 @@ module Wavefront
|
|
22
22
|
DEFAULT_PREFIX_LENGTH = 1
|
23
23
|
DEFAULT_STRICT = true
|
24
24
|
DEFAULT_OBSOLETE_METRICS = false
|
25
|
-
FORMATS = [ :raw, :ruby, :graphite, :highcharts ]
|
25
|
+
FORMATS = [ :raw, :ruby, :graphite, :highcharts, :human ]
|
26
|
+
ALERT_FORMATS = [:ruby, :json, :human]
|
27
|
+
DEFAULT_ALERT_FORMAT = :human
|
26
28
|
GRANULARITIES = %w( s m h d )
|
27
29
|
end
|
28
30
|
end
|
data/lib/wavefront/response.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
Copyright 2015 Wavefront Inc.
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
you may not use this file except in compliance with the License.
|
@@ -39,7 +39,7 @@ module Wavefront
|
|
39
39
|
class Ruby
|
40
40
|
include JSON
|
41
41
|
attr_reader :response, :options
|
42
|
-
|
42
|
+
|
43
43
|
def initialize(response, options={})
|
44
44
|
@response = response
|
45
45
|
@options = options
|
@@ -59,7 +59,7 @@ module Wavefront
|
|
59
59
|
def initialize(response, options={})
|
60
60
|
super
|
61
61
|
options[:prefix_length] ||= Wavefront::Client::DEFAULT_PREFIX_LENGTH
|
62
|
-
|
62
|
+
|
63
63
|
@graphite = Array.new
|
64
64
|
self.timeseries.each do |ts|
|
65
65
|
|
@@ -72,7 +72,7 @@ module Wavefront
|
|
72
72
|
end
|
73
73
|
|
74
74
|
output_timeseries['datapoints'] = datapoints
|
75
|
-
@graphite << output_timeseries
|
75
|
+
@graphite << output_timeseries
|
76
76
|
|
77
77
|
end
|
78
78
|
end
|
@@ -111,5 +111,38 @@ module Wavefront
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
class Human < Wavefront::Response::Ruby
|
115
|
+
#
|
116
|
+
# Print "human-readable" (but also easily machine-pareseable)
|
117
|
+
# values.
|
118
|
+
#
|
119
|
+
attr_reader :response, :options, :human
|
120
|
+
|
121
|
+
def initialize(response, options={})
|
122
|
+
super
|
123
|
+
|
124
|
+
if self.respond_to?(:timeseries)
|
125
|
+
out = ['%-20s%s' % ['query', self.query]]
|
126
|
+
|
127
|
+
self.timeseries.each_with_index do |ts, i|
|
128
|
+
out.<< '%-20s%s' % ['timeseries', i]
|
129
|
+
out += ts.select{|k,v| k != 'data' }.map do |k, v|
|
130
|
+
if k == 'tags'
|
131
|
+
v.map { |tk, tv| 'tag.%-16s%s' % [tk, tv] }
|
132
|
+
else
|
133
|
+
'%-20s%s' % [k, v]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
out += ts['data'].map do |t, v|
|
137
|
+
[Time.at(t).strftime('%F %T'), v].join(' ')
|
138
|
+
end
|
139
|
+
end
|
140
|
+
else
|
141
|
+
out = self.warnings
|
142
|
+
end
|
143
|
+
|
144
|
+
@human = out.join("\n")
|
145
|
+
end
|
146
|
+
end
|
114
147
|
end
|
115
148
|
end
|
data/wavefront-client.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
Copyright 2015 Wavefront Inc.
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
you may not use this file except in compliance with the License.
|
@@ -40,6 +40,7 @@ Gem::Specification.new do |spec|
|
|
40
40
|
|
41
41
|
spec.add_dependency "rest-client", ">= 1.6.7", "<= 1.8"
|
42
42
|
spec.add_dependency "slop", ">= 3.4.7", "<= 3.6"
|
43
|
+
spec.add_dependency 'inifile', '3.0.0'
|
43
44
|
spec.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
|
44
45
|
|
45
46
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wavefront-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Pointer
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2016-05-
|
16
|
+
date: 2016-05-20 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: bundler
|
@@ -97,6 +97,20 @@ dependencies:
|
|
97
97
|
- - <=
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '3.6'
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: inifile
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - '='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 3.0.0
|
107
|
+
type: :runtime
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - '='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 3.0.0
|
100
114
|
description: A simple abstraction for talking to wavefront in ruby
|
101
115
|
email:
|
102
116
|
- support@wavefront.com
|