wavefront-sdk 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0952995059b2df5a2e5cb7397196778b71980772aab6d1dde45159bba1ab2df6
4
- data.tar.gz: 59c74424a6a87e417048ba9a39c4a933e499dbfad5ed07a5bc94720847fe113d
3
+ metadata.gz: b87526142545d12d92b9772ceaf89a740b3c1ebdc0ffc43917721bc07052afdf
4
+ data.tar.gz: 0a57d859684bd0041a40aaeb28460191472cc1d972453525b5d5619fdea315fe
5
5
  SHA512:
6
- metadata.gz: b91d2f04af892dade0a9884bb7d2dca7e21dd9b9eae2406c4035dcb1e36d38232d773805acf2ca87716cb04e7a188b239e7d964d082ba9eea4006738b91ff41e
7
- data.tar.gz: ffba7fc41db91a7ab163db580540c127b139d545daff17c9a6af0347b0ec55d5c9c4cd81f3d6231efa0d6782a228962ca4c04eaca27b859ce1dbf1a44aad0487
6
+ metadata.gz: b06e5be378442d4e9b079e6f9989f1d03bbc91336a8b9c75ea41175e2f3663a6f9a27a9457554b99259ef7d2fbef81bf7295bf24f4e5c9f40833f399bfafe64f
7
+ data.tar.gz: 93a03c4bd635bcff93015b811027a739231d773467778a547a29f429044cc1433bfac3b0b1cc76286d2d6087e526b4707161bd6352806de781dea008b3eb61c0
data/README.md CHANGED
@@ -94,9 +94,12 @@ Wavefront::Query.new(CREDS).query(
94
94
  )
95
95
  ```
96
96
 
97
- We can write points too, assuming we have access to a proxy, because
98
- you can't write points directly via the API. Unlike all other classes, this
99
- one requires the proxy address and port as its credential hash.
97
+ We can write points too. The `Write` class lets you send points to a
98
+ proxy, and the `Report` class sends them directly via the API.
99
+ Unlike all other classes, `Write` requires the proxy address and
100
+ port as its credential hash. `Report` has the same methods and works
101
+ in the same way, but uses the same credentials as all the other
102
+ classes.
100
103
 
101
104
  ```ruby
102
105
  require 'wavefront-sdk/write'
@@ -113,6 +116,9 @@ puts task.status.result
113
116
  #OK
114
117
  ```
115
118
 
119
+ You can send delta metrics either by manually prefixing your metric
120
+ path with a delta symbol, or by using the `write_delta()` method
121
+
116
122
  The SDK also provides a helper class for extracting credentials from a
117
123
  configuration file. If you don't supply a file, defaults will be
118
124
  used.
@@ -228,6 +228,10 @@ module Wavefront
228
228
  end.lazy
229
229
  end
230
230
 
231
+ def api_path
232
+ ['', 'api', 'v2', api_base].uri_concat
233
+ end
234
+
231
235
  private
232
236
 
233
237
  # Try to describe the actual HTTP calls we make. There's a bit
@@ -269,7 +273,7 @@ module Wavefront
269
273
  @net = { headers: { 'Authorization': "Bearer #{creds[:token]}",
270
274
  'user-agent': creds[:agent] },
271
275
  endpoint: creds[:endpoint],
272
- api_base: ['', 'api', 'v2', api_base].uri_concat }
276
+ api_base: api_path }
273
277
  end
274
278
  end
275
279
  end
@@ -0,0 +1,186 @@
1
+ require 'socket'
2
+ require_relative './constants'
3
+ require_relative './base'
4
+
5
+ HOSTNAME = Socket.gethostname.freeze
6
+
7
+ module Wavefront
8
+ #
9
+ # This class helps you send points to Wavefront. It is extended by
10
+ # the Write and Report classes, which respectively handle point
11
+ # ingestion by a proxy and directly to the API.
12
+ #
13
+ class BaseWrite < Base
14
+ attr_reader :sock, :summary
15
+
16
+ # Construct an object which allows us to write points to a
17
+ # Wavefront proxy.
18
+ #
19
+ # @param _creds [Hash] dummy parameter for correct method
20
+ # signature.
21
+ # @param options [Hash] can contain the following keys:
22
+ # proxy [String] the address of the Wavefront proxy. ('wavefront')
23
+ # port [Integer] the port of the Wavefront proxy (2878)
24
+ # tags [Hash] point tags which will be applied to every point
25
+ # noop [Bool] if true, no proxy connection will be made, and
26
+ # instead of sending the points, they will be printed in
27
+ # Wavefront wire format.
28
+ # novalidate [Bool] if true, points will not be validated.
29
+ # This might make things go marginally quicker if you have
30
+ # done point validation higher up in the chain.
31
+ # verbose [Bool]
32
+ # debug [Bool]
33
+ #
34
+ def post_initialize(_creds = {}, options = {})
35
+ defaults = { tags: nil,
36
+ noop: false,
37
+ novalidate: false,
38
+ verbose: false,
39
+ debug: false }
40
+
41
+ @summary = { sent: 0, rejected: 0, unsent: 0 }
42
+ @opts = setup_options(options, defaults)
43
+
44
+ wf_point_tags?(opts[:tags]) if opts[:tags]
45
+ end
46
+
47
+ def setup_options(user, defaults)
48
+ defaults.merge(user)
49
+ end
50
+
51
+ # Send multiple points to Wavefront.
52
+ #
53
+ # @param points [Array[Hash]] an array of points. Each point is
54
+ # defined as a hash with the following keys:
55
+ # path [String] metric path. (mandatory)
56
+ # value [Numeric] value of metric. Numeric. Mandatory.
57
+ # ts [Time, Integer] timestamp for point. Defaults to
58
+ # current UTC time.
59
+ # source [String] originating source of metric. Defaults to
60
+ # the local hostname.
61
+ # tags [Hash] key: value point tags which will be applied in
62
+ # addition to any tags defined in the #initialize()
63
+ # method.
64
+ # @param openclose [Bool] if this is false, you must have
65
+ # already opened a socket to the proxy. If it is true, a
66
+ # connection will be opened for you, used, and closed.
67
+ # @param prefix [String] prefix all metrics with this string. No
68
+ # trailing dot is required.
69
+ # @raise any unhandled point validation error is passed through
70
+ # @return true if no points are rejected, otherwise false
71
+ #
72
+ def write(points = [], openclose = true, prefix = nil)
73
+ open if openclose
74
+
75
+ begin
76
+ _write_loop(prepped_points(points, prefix))
77
+ ensure
78
+ close if openclose
79
+ end
80
+
81
+ s_str = summary_string(summary)
82
+
83
+ resp = { status: { result: s_str, message: nil, code: nil },
84
+ response: summary }.to_json
85
+
86
+ Wavefront::Response.new(resp, nil)
87
+ end
88
+
89
+ def summary_string(summary)
90
+ summary[:unsent].zero? && summary[:rejected].zero? ? 'OK' : 'ERROR'
91
+ end
92
+
93
+ # @return [Array] of points
94
+ #
95
+ def prepped_points(points, prefix = nil)
96
+ ret = [points].flatten
97
+
98
+ if prefix
99
+ ret.map! { |pt| pt.tap { |p| p[:path] = prefix + '.' + p[:path] } }
100
+ end
101
+
102
+ ret
103
+ end
104
+
105
+ # A wrapper method around #write() which guarantees all points
106
+ # will be sent as deltas. You can still manually prefix any
107
+ # metric with a delta symbol and use #write(), but depending on
108
+ # your use-case, this method may be safer. It's easy to forget
109
+ # the delta.
110
+ #
111
+ # @param points [Array[Hash]] see #write()
112
+ # @param openclose [Bool] see #write()
113
+ #
114
+ def write_delta(points, openclose = true)
115
+ write(paths_to_deltas(points), openclose)
116
+ end
117
+
118
+ # Prefix all paths in a points array (as passed to
119
+ # #write_delta() with a delta symbol
120
+ #
121
+ # @param points [Array[Hash]] see #write()
122
+ # @return [Array[Hash]]
123
+ #
124
+ def paths_to_deltas(points)
125
+ [points].flatten.map { |p| p.tap { p[:path] = DELTA + p[:path] } }
126
+ end
127
+
128
+ # rubocop:disable Metrics/MethodLength
129
+ def valid_point?(point)
130
+ return true if opts[:novalidate]
131
+
132
+ begin
133
+ wf_point?(point)
134
+ return true
135
+ rescue Wavefront::Exception::InvalidMetricName,
136
+ Wavefront::Exception::InvalidMetricValue,
137
+ Wavefront::Exception::InvalidTimestamp,
138
+ Wavefront::Exception::InvalidSourceId,
139
+ Wavefront::Exception::InvalidTag => e
140
+ log('Invalid point, skipping.', :info)
141
+ log("Invalid point: #{point}. (#{e})", :debug)
142
+ summary[:rejected] += 1
143
+ return false
144
+ end
145
+ end
146
+
147
+ # Convert a validated point to a string conforming to
148
+ # https://community.wavefront.com/docs/DOC-1031. No validation
149
+ # is done here.
150
+ #
151
+ # @param point [Hash] a hash describing a point. See #write() for
152
+ # the format.
153
+ #
154
+ # rubocop:disable Metrics/AbcSize
155
+ # rubocop:disable Metrics/CyclomaticComplexity
156
+ def hash_to_wf(point)
157
+ unless point.key?(:path) && point.key?(:value)
158
+ raise Wavefront::Exception::InvalidPoint
159
+ end
160
+
161
+ point[:source] = HOSTNAME unless point.key?(:source)
162
+
163
+ m = [point[:path], point[:value]]
164
+ m.<< point[:ts] if point[:ts]
165
+ m.<< 'source=' + point[:source]
166
+ m.<< point[:tags].to_wf_tag if point[:tags]
167
+ m.<< opts[:tags].to_wf_tag if opts[:tags]
168
+ m.join(' ')
169
+ end
170
+
171
+ # Wrapper for #really_send_point(), which really sends points.
172
+ #
173
+ # @param point [String] a point description, probably from
174
+ # #hash_to_wf()
175
+ #
176
+ def send_point(point)
177
+ if opts[:noop]
178
+ log "Would send: #{point}"
179
+ return
180
+ end
181
+
182
+ log("Sending: #{point}", :info)
183
+ really_send_point(point)
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'base_write'
2
+
3
+ module Wavefront
4
+ #
5
+ # This class helps you send points direct to the Wavefront API.
6
+ #
7
+ # The points are prepped in the BaseWrite class, which this
8
+ # extends. This class provides the transport mechanism.
9
+ #
10
+ class Report < BaseWrite
11
+ def api_path
12
+ '/report'
13
+ end
14
+
15
+ def write(points = [], _openclose = true, prefix = nil)
16
+ _write_loop(prepped_points(points, prefix))
17
+ end
18
+
19
+ def really_send_point(point)
20
+ api_post('/?f=graphite_v2', point, 'application/octet-stream')
21
+ end
22
+
23
+ private
24
+
25
+ # Because API calls are expensive (compared to hitting a local
26
+ # proxy) we will bundle up points into a single call.
27
+ #
28
+ def _write_loop(points)
29
+ send_point(points.map { |p| hash_to_wf(p) }.join("\n"))
30
+ end
31
+ end
32
+ end
@@ -29,6 +29,8 @@ module Wavefront
29
29
  # response cannot be parsed. This may be because the API
30
30
  # has changed underneath us.
31
31
  #
32
+ # rubocop:disable Metrics/CyclomaticComplexity
33
+ # rubocop:disable Metrics/PerceivedComplexity
32
34
  def initialize(json, status, debug = false)
33
35
  raw = raw_response(json, status)
34
36
  @status = build_status(raw, status)
@@ -90,7 +92,7 @@ module Wavefront
90
92
 
91
93
  @result = if obj[:result]
92
94
  obj[:result]
93
- elsif status == 200
95
+ elsif status >= 200 && status <= 299
94
96
  'OK'
95
97
  else
96
98
  'ERROR'
@@ -1 +1 @@
1
- WF_SDK_VERSION = '1.3.2'.freeze
1
+ WF_SDK_VERSION = '1.4.0'.freeze
@@ -1,207 +1,15 @@
1
- require 'socket'
2
- require_relative './constants'
3
- require_relative './base'
4
-
5
- HOSTNAME = Socket.gethostname.freeze
1
+ require_relative './base_write'
6
2
 
7
3
  module Wavefront
8
4
  #
9
5
  # This class helps you send points to a Wavefront proxy in native
10
6
  # format. Usually this is done on port 2878.
11
7
  #
12
- # rubocop:disable Metrics/ClassLength
13
- class Write < Base
14
- attr_reader :sock, :summary
15
-
16
- # Construct an object which allows us to write points to a
17
- # Wavefront proxy.
18
- #
19
- # @param _creds [Hash] dummy parameter for correct method
20
- # signature.
21
- # @param options [Hash] can contain the following keys:
22
- # proxy [String] the address of the Wavefront proxy. ('wavefront')
23
- # port [Integer] the port of the Wavefront proxy (2878)
24
- # tags [Hash] point tags which will be applied to every point
25
- # noop [Bool] if true, no proxy connection will be made, and
26
- # instead of sending the points, they will be printed in
27
- # Wavefront wire format.
28
- # novalidate [Bool] if true, points will not be validated.
29
- # This might make things go marginally quicker if you have
30
- # done point validation higher up in the chain.
31
- # verbose [Bool]
32
- # debug [Bool]
33
- #
34
- def post_initialize(_creds = {}, options = {})
35
- defaults = { tags: nil,
36
- noop: false,
37
- novalidate: false,
38
- verbose: false,
39
- debug: false }
40
-
41
- @summary = { sent: 0, rejected: 0, unsent: 0 }
42
- @opts = setup_options(options, defaults)
43
-
44
- wf_point_tags?(opts[:tags]) if opts[:tags]
45
- end
46
-
47
- def setup_options(user, defaults)
48
- defaults.merge(user)
49
- end
50
-
51
- # Send raw data to a Wavefront proxy, automatically opening and
52
- # closing a socket.
53
- #
54
- # @param points [Array[String]] an array of points in native
55
- # Wavefront wire format, as described in
56
- # https://community.wavefront.com/docs/DOC-1031. No validation
57
- # is performed.
58
- # @param openclose [Boolean] whether or not to automatically
59
- # open a socket to the proxy before sending points, and
60
- # afterwards, close it.
61
- #
62
- def raw(points, openclose = true)
63
- open if openclose
64
-
65
- begin
66
- [points].flatten.each { |p| send_point(p) }
67
- ensure
68
- close if openclose
69
- end
70
- end
71
-
72
- # Send multiple points to a Wavefront proxy.
73
- #
74
- # @param points [Array[Hash]] an array of points. Each point is
75
- # defined as a hash with the following keys:
76
- # path [String] metric path. (mandatory)
77
- # value [Numeric] value of metric. Numeric. Mandatory.
78
- # ts [Time, Integer] timestamp for point. Defaults to
79
- # current UTC time.
80
- # source [String] originating source of metric. Defaults to
81
- # the local hostname.
82
- # tags [Hash] key: value point tags which will be applied in
83
- # addition to any tags defined in the #initialize()
84
- # method.
85
- # @param openclose [Bool] if this is false, you must have
86
- # already opened a socket to the proxy. If it is true, a
87
- # connection will be opened for you, used, and closed.
88
- # @param prefix [String] prefix all metrics with this string. No
89
- # trailing dot is required.
90
- # @raise any unhandled point validation error is passed through
91
- # @return true if no points are rejected, otherwise false
92
- #
93
- def write(points = [], openclose = true, prefix = nil)
94
- open if openclose
95
-
96
- begin
97
- _write_loop(prepped_points(points, prefix))
98
- ensure
99
- close if openclose
100
- end
101
-
102
- s_str = summary_string(summary)
103
-
104
- resp = { status: { result: s_str, message: nil, code: nil },
105
- response: summary }.to_json
106
-
107
- Wavefront::Response.new(resp, nil)
108
- end
109
-
110
- def summary_string(summary)
111
- summary[:unsent].zero? && summary[:rejected].zero? ? 'OK' : 'ERROR'
112
- end
113
-
114
- # @return [Array] of points
115
- #
116
- def prepped_points(points, prefix = nil)
117
- ret = [points].flatten
118
-
119
- if prefix
120
- ret.map! { |pt| pt.tap { |p| p[:path] = prefix + '.' + p[:path] } }
121
- end
122
-
123
- ret
124
- end
125
-
126
- # A wrapper method around #write() which guarantees all points
127
- # will be sent as deltas. You can still manually prefix any
128
- # metric with a delta symbol and use #write(), but depending on
129
- # your use-case, this method may be safer. It's easy to forget
130
- # the delta.
131
- #
132
- # @param points [Array[Hash]] see #write()
133
- # @param openclose [Bool] see #write()
134
- #
135
- def write_delta(points, openclose = true)
136
- write(paths_to_deltas(points), openclose)
137
- end
138
-
139
- # Prefix all paths in a points array (as passed to
140
- # #write_delta() with a delta symbol
141
- #
142
- # @param points [Array[Hash]] see #write()
143
- # @return [Array[Hash]]
144
- #
145
- def paths_to_deltas(points)
146
- [points].flatten.map { |p| p.tap { p[:path] = DELTA + p[:path] } }
147
- end
148
-
149
- # rubocop:disable Metrics/MethodLength
150
- def valid_point?(point)
151
- return true if opts[:novalidate]
152
-
153
- begin
154
- wf_point?(point)
155
- return true
156
- rescue Wavefront::Exception::InvalidMetricName,
157
- Wavefront::Exception::InvalidMetricValue,
158
- Wavefront::Exception::InvalidTimestamp,
159
- Wavefront::Exception::InvalidSourceId,
160
- Wavefront::Exception::InvalidTag => e
161
- log('Invalid point, skipping.', :info)
162
- log("Invalid point: #{point}. (#{e})", :debug)
163
- summary[:rejected] += 1
164
- return false
165
- end
166
- end
167
-
168
- # Convert a validated point to a string conforming to
169
- # https://community.wavefront.com/docs/DOC-1031. No validation
170
- # is done here.
171
- #
172
- # @param point [Hash] a hash describing a point. See #write() for
173
- # the format.
174
- #
175
- # rubocop:disable Metrics/AbcSize
176
- # rubocop:disable Metrics/CyclomaticComplexity
177
- def hash_to_wf(point)
178
- unless point.key?(:path) && point.key?(:value)
179
- raise Wavefront::Exception::InvalidPoint
180
- end
181
-
182
- point[:source] = HOSTNAME unless point.key?(:source)
183
-
184
- m = [point[:path], point[:value]]
185
- m.<< point[:ts] if point[:ts]
186
- m.<< 'source=' + point[:source]
187
- m.<< point[:tags].to_wf_tag if point[:tags]
188
- m.<< opts[:tags].to_wf_tag if opts[:tags]
189
- m.join(' ')
190
- end
191
-
192
- # Send a point which is already in Wavefront wire format.
193
- #
194
- # @param point [String] a point description, probably from
195
- # #hash_to_wf()
196
- #
197
- def send_point(point)
198
- if opts[:noop]
199
- log "Would send: #{point}"
200
- return
201
- end
202
-
203
- log("Sending: #{point}", :info)
204
-
8
+ # The points are prepped in the BaseWrite class, which this
9
+ # extends. This class provides the transport mechanism.
10
+ #
11
+ class Write < BaseWrite
12
+ def really_send_point(point)
205
13
  begin
206
14
  sock.puts(point)
207
15
  rescue StandardError => e
@@ -218,6 +26,7 @@ module Wavefront
218
26
  # Open a socket to a Wavefront proxy, putting the descriptor
219
27
  # in instance variable @sock.
220
28
  #
29
+ # rubocop:disable Metrics/MethodLength
221
30
  def open
222
31
  if opts[:noop]
223
32
  log('No-op requested. Not opening connection to proxy.')
@@ -225,7 +34,6 @@ module Wavefront
225
34
  end
226
35
 
227
36
  port = net[:port] || 2878
228
-
229
37
  log("Connecting to #{net[:proxy]}:#{port}.", :info)
230
38
 
231
39
  begin
@@ -244,6 +52,35 @@ module Wavefront
244
52
  sock.close
245
53
  end
246
54
 
55
+ # Overload the method which sets an API endpoint. A proxy
56
+ # endpoint has an address and a port, rather than an address and
57
+ # a token.
58
+ #
59
+ def setup_endpoint(creds)
60
+ @net = creds
61
+ end
62
+
63
+ # Send raw data to a Wavefront proxy, automatically opening and
64
+ # closing a socket.
65
+ #
66
+ # @param points [Array[String]] an array of points in native
67
+ # Wavefront wire format, as described in
68
+ # https://community.wavefront.com/docs/DOC-1031. No validation
69
+ # is performed.
70
+ # @param openclose [Boolean] whether or not to automatically
71
+ # open a socket to the proxy before sending points, and
72
+ # afterwards, close it.
73
+ #
74
+ def raw(points, openclose = true)
75
+ open if openclose
76
+
77
+ begin
78
+ [points].flatten.each { |p| send_point(p) }
79
+ ensure
80
+ close if openclose
81
+ end
82
+ end
83
+
247
84
  private
248
85
 
249
86
  def _write_loop(points)
@@ -252,13 +89,5 @@ module Wavefront
252
89
  send_point(hash_to_wf(p))
253
90
  end
254
91
  end
255
-
256
- # Overload the method which sets an API endpoint. A proxy
257
- # endpoint has an address and a port, rather than an address and
258
- # a token.
259
- #
260
- def setup_endpoint(creds)
261
- @net = creds
262
- end
263
92
  end
264
93
  end
@@ -28,7 +28,7 @@ DUMMY_RESPONSE = '{"status":{"result":"OK","message":"","code":200},' \
28
28
 
29
29
  # Common testing code
30
30
  class WavefrontTestBase < MiniTest::Test
31
- attr_reader :wf, :wf_noop, :uri_base, :headers
31
+ attr_reader :wf, :wf_noop, :headers
32
32
 
33
33
  def initialize(args)
34
34
  require_relative "../lib/wavefront-sdk/#{class_basename.downcase}"
@@ -46,10 +46,14 @@ class WavefrontTestBase < MiniTest::Test
46
46
  def setup
47
47
  klass = Object.const_get('Wavefront').const_get(class_basename)
48
48
  @wf = klass.new(CREDS)
49
- @uri_base = "https://#{CREDS[:endpoint]}/api/v2/" + api_base
49
+ @uri_base = uri_base
50
50
  @headers = { 'Authorization' => "Bearer #{CREDS[:token]}" }
51
51
  end
52
52
 
53
+ def uri_base
54
+ "https://#{CREDS[:endpoint]}/api/v2/" + api_base
55
+ end
56
+
53
57
  def target_uri(path)
54
58
  [uri_base, path].join(path.start_with?('?') ? '' : '/')
55
59
  end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../spec_helper'
4
+
5
+ HEADERS = POST_HEADERS.merge('Content-Type': 'application/octet-stream')
6
+ # Unit tests for Report class
7
+ #
8
+ class WavefrontReportTest < WavefrontTestBase
9
+ def uri_base
10
+ "https://#{CREDS[:endpoint]}/report"
11
+ end
12
+
13
+ def test_write
14
+ should_work(:write, POINT, ['?f=graphite_v2', nil],
15
+ :post, HEADERS, POINT_L)
16
+ end
17
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wavefront-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Fisher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-03 00:00:00.000000000 Z
11
+ date: 2018-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -194,6 +194,7 @@ files:
194
194
  - Rakefile
195
195
  - lib/wavefront-sdk/alert.rb
196
196
  - lib/wavefront-sdk/base.rb
197
+ - lib/wavefront-sdk/base_write.rb
197
198
  - lib/wavefront-sdk/cloudintegration.rb
198
199
  - lib/wavefront-sdk/constants.rb
199
200
  - lib/wavefront-sdk/credentials.rb
@@ -210,6 +211,7 @@ files:
210
211
  - lib/wavefront-sdk/parse_time.rb
211
212
  - lib/wavefront-sdk/proxy.rb
212
213
  - lib/wavefront-sdk/query.rb
214
+ - lib/wavefront-sdk/report.rb
213
215
  - lib/wavefront-sdk/response.rb
214
216
  - lib/wavefront-sdk/savedsearch.rb
215
217
  - lib/wavefront-sdk/search.rb
@@ -238,6 +240,7 @@ files:
238
240
  - spec/wavefront-sdk/parse_time_spec.rb
239
241
  - spec/wavefront-sdk/proxy_spec.rb
240
242
  - spec/wavefront-sdk/query_spec.rb
243
+ - spec/wavefront-sdk/report_spec.rb
241
244
  - spec/wavefront-sdk/resources/test.conf
242
245
  - spec/wavefront-sdk/resources/test2.conf
243
246
  - spec/wavefront-sdk/response_spec.rb
@@ -292,6 +295,7 @@ test_files:
292
295
  - spec/wavefront-sdk/parse_time_spec.rb
293
296
  - spec/wavefront-sdk/proxy_spec.rb
294
297
  - spec/wavefront-sdk/query_spec.rb
298
+ - spec/wavefront-sdk/report_spec.rb
295
299
  - spec/wavefront-sdk/resources/test.conf
296
300
  - spec/wavefront-sdk/resources/test2.conf
297
301
  - spec/wavefront-sdk/response_spec.rb