wavefront-client 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTkyYWUzNzQ3MTVmYjhlNGI3NWZlZDM5YTBjYTAwMzNkMTQ2MjQ0YQ==
4
+ MjE5OWM5OWIyYjcxNWI2MGJjNGRiOWI1YjBlMjI1OWFiMzIyMWVjYg==
5
5
  data.tar.gz: !binary |-
6
- NDNlN2ZiNmYxNDE0NzhlMzdjMTJhNjExZGI4ZjhhY2Q0YWE5YjViMw==
6
+ OGJkZTg1ZTgwMDdjMmZhZDhiYjIyZDVlYmJlYzMzNGZiZDI4ZWEyOQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YzQxYzE3NGZmNzkwNWRjYzgxYWM0MDBhNDk5OGM1NGZlMjE4MDA2ZWI2YTNi
10
- YTRhNTQxYTIzYzFhNWRlYTgxYzIyNWI1OTgwNTA1ZWE0NjFmMjY0M2Y2ODg3
11
- ZmVlOTJmZDk2YTdiYjVkOGEzOTUzYTMwYjk3NTU5NjVkOWRjZjI=
9
+ YTBhNmI4OWJmOWJlM2I2NDMwYTNhNjIzMGNjZjM0OWVlMjdjMzU1YWUwNjYy
10
+ MTZjYjIwYjI2MDhlNDU3ZmJjYmZjODk1NmY0ZTM0OGJlMzMzMDJjZmNjN2Jk
11
+ MDk4N2MxODQzYzQ0MDQxMzRkY2Y2YzMwOWE3ODA3ZGFjZDA2MGM=
12
12
  data.tar.gz: !binary |-
13
- MDljMjNlYzg3YTJhNjY0YWQ3MDA0Y2M2ZDYyOWVjMzlkOTA5NzEyMjJhMzNl
14
- NmFhMjVmMjI4MDAyNjEzNTc1OTlmOWE5ZWYyY2Y4MzY2ZDg5ODAzOTI2OGEw
15
- ZTg0NWFiZGQyOTNhZGRkYmEyNmE3ZGNiMzI2NmIxYjBmNjY1NmE=
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
- -d, --days Query granularity of days
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
- -E, --endpoint Connect to alternative cluster endpoint (default: metrics.wavefront.com)
188
- -S, --seconds Query granularity of seconds
189
- -s, --start Time in UNIX epoch seconds to begin the query from
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
- -e, --end Time in UNIX epoch seconds to query to
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 'd', 'days', 'Query granularity of days'
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 'E', 'endpoint=', 'Connect to alternative cluster endpoint', default: Wavefront::Client::DEFAULT_HOST.to_s
30
- on 'S', 'seconds', 'Query granularity of seconds'
31
- on 's', 'start=', 'Time in UNIX epoch seconds to begin the query from'
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 'e', 'end=', 'Time in UNIX epoch seconds to query to'
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=', 'The number of path elements to treat as a prefix when doing schema manipulations', default: Wavefront::Client::DEFAULT_PREFIX_LENGTH
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=', 'Flag to include metrics that have not been reporting for more than 4 weeks,defaults to false', default: Wavefront::Client::DEFAULT_OBSOLETE_METRICS
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
- cli.run
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, arguments)
57
- cli.run
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
@@ -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[0]
31
- query = arguments[0].to_sym
32
- else
33
- puts "Your query should be one of: #{ queries.each {|q| q.to_s}.join(', ') }. See --help for more information"
34
- exit 1
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
- if queries.include?(query)
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
@@ -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
- if @options.minutes?
38
+
39
+ if @options[:minutes]
28
40
  granularity = 'm'
29
- elsif @options.hours?
41
+ elsif @options[:hours]
30
42
  granularity = 'h'
31
- elsif @options.seconds?
43
+ elsif @options[:seconds]
32
44
  granularity = 's'
33
- elsif @options.days?
45
+ elsif @options[:days]
34
46
  granularity = 'd'
35
47
  else
36
- puts "You must specify a granularity of either --seconds, --minutes --hours or --days. See --help for more information."
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
- puts "The output format must be on of #{Wavefront::Client::FORMATS.join(', ')}"
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] = Time.at(@options[:start].to_i)
60
+ options[:start_time] = parse_time(@options[:start])
51
61
  end
52
62
 
53
63
  if @options[:end]
54
- options[:end_time] = Time.at(@options[:end].to_i)
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.help?
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
@@ -16,6 +16,6 @@ See the License for the specific language governing permissions and
16
16
 
17
17
  module Wavefront
18
18
  class Client
19
- VERSION = "3.0.0"
19
+ VERSION = "3.1.0"
20
20
  end
21
21
  end
@@ -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
@@ -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
@@ -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
@@ -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.0.0
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 00:00:00.000000000 Z
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