wavefront-sdk 1.6.0 → 1.6.1
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 +4 -4
- data/.rubocop.yml +9 -2
- data/HISTORY.md +11 -0
- data/lib/wavefront-sdk/base.rb +31 -46
- data/lib/wavefront-sdk/base_write.rb +28 -29
- data/lib/wavefront-sdk/event.rb +11 -7
- data/lib/wavefront-sdk/exception.rb +1 -0
- data/lib/wavefront-sdk/externallink.rb +2 -1
- data/lib/wavefront-sdk/logger.rb +65 -0
- data/lib/wavefront-sdk/metric.rb +5 -6
- data/lib/wavefront-sdk/mixins.rb +16 -5
- data/lib/wavefront-sdk/response.rb +36 -25
- data/lib/wavefront-sdk/search.rb +2 -2
- data/lib/wavefront-sdk/stdlib/hash.rb +6 -1
- data/lib/wavefront-sdk/validators.rb +123 -115
- data/lib/wavefront-sdk/version.rb +1 -1
- data/lib/wavefront-sdk/write.rb +0 -1
- data/spec/wavefront-sdk/base_write_spec.rb +82 -0
- data/spec/wavefront-sdk/logger_spec.rb +62 -0
- data/spec/wavefront-sdk/mixins_spec.rb +17 -0
- data/spec/wavefront-sdk/resources/dummy_points.rb +20 -0
- data/spec/wavefront-sdk/write_spec.rb +3 -79
- data/wavefront-sdk.gemspec +1 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e599fd70e3a67cdc62c8ec942382db101850582e8bd98c11e8e56e18a1d1bfaf
|
4
|
+
data.tar.gz: 134f436ff650ba75a4cad1e93bcf229ea25787dbafa5fcf40aa93b067bed9402
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f051f1594d486c3b6c65ed964a0e2b822a034975a19ad9745926048e891ce5a8f89a063a17532ff8a90b3b1c89085ba448d57346dff33b6300765bd3f365b3e
|
7
|
+
data.tar.gz: 0a97bf0ed08c8ee08607b4e98f55cc5daeb7b30e6245df99407c0dddfb708ed093bbaeb3d9aaac805d09da12ca61cccdd94c96222458545bc7857d536d43002e
|
data/.rubocop.yml
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
---
|
1
2
|
AllCops:
|
2
|
-
TargetRubyVersion: 2.
|
3
|
+
TargetRubyVersion: 2.2
|
3
4
|
|
4
5
|
Style/FrozenStringLiteralComment:
|
5
6
|
Enabled: false
|
6
7
|
|
7
|
-
|
8
|
+
Style/FormatStringToken:
|
8
9
|
Enabled: false
|
10
|
+
|
11
|
+
Metrics/ClassLength:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Metrics/MethodLength:
|
15
|
+
Max: 13
|
data/HISTORY.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.6.1 (22/08/2018)
|
4
|
+
|
5
|
+
* Fix Ruby 2.2 bugs
|
6
|
+
* Improve unit test separation
|
7
|
+
* Allow updating of all external link parameters
|
8
|
+
|
9
|
+
## 1.6.0 (07/08/2018)
|
10
|
+
* Improve validation of point tags.
|
11
|
+
* Break extensions to standard library out into their own files.
|
12
|
+
* Improve README.
|
13
|
+
|
3
14
|
## 1.5.0 (25/06/2018)
|
4
15
|
|
5
16
|
* Add [derived
|
data/lib/wavefront-sdk/base.rb
CHANGED
@@ -4,6 +4,7 @@ require 'faraday'
|
|
4
4
|
require 'pp'
|
5
5
|
require 'ostruct'
|
6
6
|
require 'addressable'
|
7
|
+
require_relative 'logger'
|
7
8
|
require_relative 'exception'
|
8
9
|
require_relative 'mixins'
|
9
10
|
require_relative 'response'
|
@@ -18,12 +19,11 @@ module Wavefront
|
|
18
19
|
#
|
19
20
|
# @return a Wavefront::Response object
|
20
21
|
#
|
21
|
-
# rubocop:disable Metrics/ClassLength
|
22
22
|
class Base
|
23
23
|
include Wavefront::Validators
|
24
24
|
include Wavefront::Mixins
|
25
|
-
attr_reader :opts, :debug, :noop, :verbose, :net, :conn,
|
26
|
-
:logger
|
25
|
+
attr_reader :opts, :debug, :noop, :verbose, :net, :conn,
|
26
|
+
:update_keys, :logger
|
27
27
|
|
28
28
|
# Create a new API object. This will always be called from a
|
29
29
|
# class which inherits this one. If the inheriting class defines
|
@@ -44,16 +44,19 @@ module Wavefront
|
|
44
44
|
# @return [Nil]
|
45
45
|
#
|
46
46
|
def initialize(creds = {}, opts = {})
|
47
|
-
@opts
|
48
|
-
@debug
|
49
|
-
@noop
|
47
|
+
@opts = opts
|
48
|
+
@debug = opts[:debug] || false
|
49
|
+
@noop = opts[:noop] || false
|
50
50
|
@verbose = opts[:verbose] || false
|
51
|
-
@logger
|
51
|
+
@logger = Wavefront::Logger.new(opts)
|
52
52
|
setup_endpoint(creds)
|
53
|
-
|
54
53
|
post_initialize(creds, opts) if respond_to?(:post_initialize)
|
55
54
|
end
|
56
55
|
|
56
|
+
def log(message, severity = :info)
|
57
|
+
logger.log(message, severity)
|
58
|
+
end
|
59
|
+
|
57
60
|
# Convert an epoch timestamp into epoch milliseconds. If the
|
58
61
|
# timestamp looks like it's already epoch milliseconds, return
|
59
62
|
# it as-is.
|
@@ -85,16 +88,15 @@ module Wavefront
|
|
85
88
|
# @return [URI::HTTPS]
|
86
89
|
#
|
87
90
|
def mk_conn(path, headers = {})
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
)
|
91
|
+
url = format('https://%s%s', net[:endpoint], [net[:api_base],
|
92
|
+
path].uri_concat)
|
93
|
+
Faraday.new(url: Addressable::URI.encode(url),
|
94
|
+
headers: net[:headers].merge(headers))
|
93
95
|
end
|
94
96
|
|
95
97
|
# Make a GET call to the Wavefront API and return the result as
|
96
98
|
# a Ruby hash. Can optionally perform a verbose noop, if the
|
97
|
-
#
|
99
|
+
# @noop class variable is set. If @verbose is set, then prints
|
98
100
|
# the information used to build the URI.
|
99
101
|
#
|
100
102
|
# @param path [String] path to be appended to the
|
@@ -109,7 +111,7 @@ module Wavefront
|
|
109
111
|
|
110
112
|
# Make a POST call to the Wavefront API and return the result as
|
111
113
|
# a Ruby hash. Can optionally perform a verbose noop, if the
|
112
|
-
#
|
114
|
+
# @noop class variable is set. If @verbose is set, then prints
|
113
115
|
# the information used to build the URI.
|
114
116
|
#
|
115
117
|
# @param path [String] path to be appended to the
|
@@ -127,7 +129,7 @@ module Wavefront
|
|
127
129
|
|
128
130
|
# Make a PUT call to the Wavefront API and return the result as
|
129
131
|
# a Ruby hash. Can optionally perform a verbose noop, if the
|
130
|
-
#
|
132
|
+
# @noop class variable is set. If @verbose is set, then prints
|
131
133
|
# the information used to build the URI.
|
132
134
|
#
|
133
135
|
# @param path [String] path to be appended to the
|
@@ -144,7 +146,7 @@ module Wavefront
|
|
144
146
|
|
145
147
|
# Make a DELETE call to the Wavefront API and return the result
|
146
148
|
# as a Ruby hash. Can optionally perform a verbose noop, if the
|
147
|
-
#
|
149
|
+
# @noop class variable is set. If @verbose is set, then prints
|
148
150
|
# the information used to build the URI.
|
149
151
|
#
|
150
152
|
# @param path [String] path to be appended to the
|
@@ -173,30 +175,6 @@ module Wavefront
|
|
173
175
|
end
|
174
176
|
end
|
175
177
|
|
176
|
-
# Send a message to a Ruby logger object if the user supplied
|
177
|
-
# one, or print to standard out if not.
|
178
|
-
#
|
179
|
-
# @param msg [String] the string to print
|
180
|
-
# @param level [Symbol] the level of the message.
|
181
|
-
# :verbose messages equate to a standard INFO log level and
|
182
|
-
# :debug to DEBUG.
|
183
|
-
#
|
184
|
-
def log(msg, level = nil)
|
185
|
-
if logger
|
186
|
-
logger.send(level || :info, msg)
|
187
|
-
else
|
188
|
-
print_message(msg, level)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
# Print it unless it's a debug and we're not in debug
|
193
|
-
#
|
194
|
-
def print_message(msg, level)
|
195
|
-
return if level == :debug && !opts[:debug]
|
196
|
-
return if level == :info && !opts[:verbose]
|
197
|
-
puts msg
|
198
|
-
end
|
199
|
-
|
200
178
|
# If we need to massage a raw response to fit what the
|
201
179
|
# Wavefront::Response class expects (I'm looking at you,
|
202
180
|
# 'User'), a class can provide a {#response_shim} method.
|
@@ -208,7 +186,7 @@ module Wavefront
|
|
208
186
|
resp.body
|
209
187
|
end
|
210
188
|
|
211
|
-
Wavefront::Response.new(body, resp.status,
|
189
|
+
Wavefront::Response.new(body, resp.status, opts)
|
212
190
|
end
|
213
191
|
|
214
192
|
# Return all objects using a lazy enumerator
|
@@ -238,11 +216,11 @@ module Wavefront
|
|
238
216
|
# of clumsy guesswork here
|
239
217
|
#
|
240
218
|
def verbosity(conn, method, *args)
|
241
|
-
log
|
219
|
+
log format('uri: %s %s', method.upcase, conn.url_prefix)
|
242
220
|
|
243
221
|
return unless args.last && !args.last.empty?
|
244
222
|
|
245
|
-
|
223
|
+
log method == :get ? "params: #{args.last}" : "body: #{args.last}"
|
246
224
|
end
|
247
225
|
|
248
226
|
# Make the API call, or not, if noop is set.
|
@@ -261,10 +239,17 @@ module Wavefront
|
|
261
239
|
respond(resp)
|
262
240
|
end
|
263
241
|
|
264
|
-
def
|
242
|
+
def validate_credentials(creds)
|
265
243
|
%w[endpoint token].each do |k|
|
266
|
-
|
244
|
+
unless creds.key?(k.to_sym)
|
245
|
+
raise(Wavefront::Exception::CredentialError,
|
246
|
+
format('credentials must contain %s', k))
|
247
|
+
end
|
267
248
|
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def setup_endpoint(creds)
|
252
|
+
validate_credentials(creds)
|
268
253
|
|
269
254
|
unless creds.key?(:agent) && creds[:agent]
|
270
255
|
creds[:agent] = "wavefront-sdk #{WF_SDK_VERSION}"
|
@@ -83,7 +83,7 @@ module Wavefront
|
|
83
83
|
resp = { status: { result: s_str, message: nil, code: nil },
|
84
84
|
response: summary }.to_json
|
85
85
|
|
86
|
-
Wavefront::Response.new(resp, nil)
|
86
|
+
Wavefront::Response.new(resp, nil, opts)
|
87
87
|
end
|
88
88
|
|
89
89
|
def summary_string(summary)
|
@@ -125,23 +125,18 @@ module Wavefront
|
|
125
125
|
[points].flatten.map { |p| p.tap { p[:path] = DELTA + p[:path] } }
|
126
126
|
end
|
127
127
|
|
128
|
-
# rubocop:disable Metrics/MethodLength
|
129
128
|
def valid_point?(point)
|
130
129
|
return true if opts[:novalidate]
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
log("Invalid point: #{point}. (#{e})", :debug)
|
142
|
-
summary[:rejected] += 1
|
143
|
-
return false
|
144
|
-
end
|
130
|
+
wf_point?(point)
|
131
|
+
rescue Wavefront::Exception::InvalidMetricName,
|
132
|
+
Wavefront::Exception::InvalidMetricValue,
|
133
|
+
Wavefront::Exception::InvalidTimestamp,
|
134
|
+
Wavefront::Exception::InvalidSourceId,
|
135
|
+
Wavefront::Exception::InvalidTag => e
|
136
|
+
log('Invalid point, skipping.', :info)
|
137
|
+
log(format('Invalid point: %s (%s)', point, e.to_s), :debug)
|
138
|
+
summary[:rejected] += 1
|
139
|
+
false
|
145
140
|
end
|
146
141
|
|
147
142
|
# Convert a validated point to a string conforming to
|
@@ -151,21 +146,25 @@ module Wavefront
|
|
151
146
|
# @param point [Hash] a hash describing a point. See #write() for
|
152
147
|
# the format.
|
153
148
|
#
|
154
|
-
# rubocop:disable Metrics/AbcSize
|
155
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
156
149
|
def hash_to_wf(point)
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
150
|
+
format('%s %s %s source=%s %s %s',
|
151
|
+
*point_array(point)).squeeze(' ').strip
|
152
|
+
rescue StandardError
|
153
|
+
raise Wavefront::Exception::InvalidPoint
|
154
|
+
end
|
162
155
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
156
|
+
# Make an array which can be used by #hash_to_wf.
|
157
|
+
# @param point [Hash] a hash describing a point. See #write() for
|
158
|
+
# the format.
|
159
|
+
# @raise
|
160
|
+
#
|
161
|
+
def point_array(point)
|
162
|
+
[point[:path] || raise,
|
163
|
+
point[:value] || raise,
|
164
|
+
point.fetch(:ts, nil),
|
165
|
+
point.fetch(:source, HOSTNAME),
|
166
|
+
point[:tags] && point[:tags].to_wf_tag,
|
167
|
+
opts[:tags] && opts[:tags].to_wf_tag]
|
169
168
|
end
|
170
169
|
|
171
170
|
# Wrapper for #really_send_point(), which really sends points.
|
data/lib/wavefront-sdk/event.rb
CHANGED
@@ -24,17 +24,21 @@ module Wavefront
|
|
24
24
|
# @return [Wavefront::Response]
|
25
25
|
#
|
26
26
|
def list(from = nil, to = nil, limit = 100, cursor = nil)
|
27
|
-
raise ArgumentError unless from && to
|
27
|
+
raise ArgumentError unless from && to && limit.is_a?(Integer)
|
28
|
+
wf_event_id?(cursor) if cursor
|
29
|
+
|
28
30
|
from = parse_time(from, true)
|
29
|
-
to
|
31
|
+
to = parse_time(to, true)
|
32
|
+
|
30
33
|
wf_ms_ts?(from)
|
31
34
|
wf_ms_ts?(to)
|
32
|
-
wf_event_id?(cursor) if cursor
|
33
|
-
raise ArgumentError unless limit.is_a?(Integer)
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
body = { earliestStartTimeEpochMillis: from,
|
37
|
+
latestStartTimeEpochMillis: to,
|
38
|
+
cursor: cursor,
|
39
|
+
limit: limit }
|
40
|
+
|
41
|
+
api_get('', body.cleanse)
|
38
42
|
end
|
39
43
|
|
40
44
|
# POST /api/v2/event
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Wavefront
|
2
|
+
#
|
3
|
+
# Log to a user-supplied Ruby logger, or to standard output.
|
4
|
+
#
|
5
|
+
class Logger
|
6
|
+
attr_reader :logger, :verbose, :debug
|
7
|
+
|
8
|
+
# @param opts [Hash] options hash from a child of Wavefront::Base
|
9
|
+
#
|
10
|
+
def initialize(opts = {})
|
11
|
+
@logger = opts[:logger] || nil
|
12
|
+
@verbose = opts[:verbose] || nil
|
13
|
+
@debug = opts[:debug] || nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# Send a message to a Ruby logger object if the user supplied
|
17
|
+
# one, or print to standard out if not.
|
18
|
+
#
|
19
|
+
# @param msg [String] the string to print
|
20
|
+
# @param level [Symbol] the level of the message.
|
21
|
+
# :verbose messages equate to a standard INFO log level and
|
22
|
+
# :debug to DEBUG.
|
23
|
+
#
|
24
|
+
def log(msg, level = :info)
|
25
|
+
if logger
|
26
|
+
logger.send(level, msg)
|
27
|
+
else
|
28
|
+
print_message(level, msg)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def print_message(level, msg)
|
33
|
+
method = format('print_%s_message', level).to_sym
|
34
|
+
msg = format_message(level, msg)
|
35
|
+
|
36
|
+
if respond_to?(:method)
|
37
|
+
send(method, msg)
|
38
|
+
else
|
39
|
+
print_warn_message(format('undefined message level:%s', level))
|
40
|
+
print_warn_message(msg)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def format_message(level, msg)
|
45
|
+
format('SDK %s: %s', level.to_s.upcase, msg)
|
46
|
+
end
|
47
|
+
|
48
|
+
def print_debug_message(msg)
|
49
|
+
return unless debug
|
50
|
+
puts msg
|
51
|
+
end
|
52
|
+
|
53
|
+
def print_info_message(msg)
|
54
|
+
puts msg
|
55
|
+
end
|
56
|
+
|
57
|
+
def print_warn_message(msg)
|
58
|
+
warn msg
|
59
|
+
end
|
60
|
+
|
61
|
+
def print_error_message(msg)
|
62
|
+
warn msg
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/wavefront-sdk/metric.rb
CHANGED
@@ -18,19 +18,18 @@ module Wavefront
|
|
18
18
|
# @param cursor [String] optionally begin from this result
|
19
19
|
#
|
20
20
|
def detail(metric, sources = [], cursor = nil)
|
21
|
-
raise ArgumentError unless metric.is_a?(String)
|
22
|
-
raise ArgumentError unless sources.is_a?(Array)
|
21
|
+
raise ArgumentError unless metric.is_a?(String) && sources.is_a?(Array)
|
23
22
|
|
24
|
-
|
23
|
+
query = [[:m, metric]]
|
25
24
|
|
26
25
|
if cursor
|
27
26
|
raise ArgumentError unless cursor.is_a?(String)
|
28
|
-
|
27
|
+
query.<< [:c, cursor]
|
29
28
|
end
|
30
29
|
|
31
|
-
sources.each { |
|
30
|
+
sources.each { |source| query.<< [:h, source] }
|
32
31
|
|
33
|
-
api_get('detail',
|
32
|
+
api_get('detail', query)
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
data/lib/wavefront-sdk/mixins.rb
CHANGED
@@ -43,18 +43,29 @@ module Wavefront
|
|
43
43
|
ref.to_i + parse_relative_time(time, in_ms)
|
44
44
|
end
|
45
45
|
|
46
|
+
# Do the real work for #relative_time
|
47
|
+
# @param time [String] as +1h, -3d etc
|
48
|
+
# @param in_ms [Bool] whether to return time differential in ms
|
49
|
+
# rather than s
|
50
|
+
# @return [Integer] time differential
|
51
|
+
#
|
46
52
|
def parse_relative_time(time, in_ms = false)
|
47
|
-
unless
|
53
|
+
unless valid_relative_time?(time)
|
48
54
|
raise Wavefront::Exception::InvalidRelativeTime
|
49
55
|
end
|
50
56
|
|
51
57
|
m = in_ms ? 1000 : 1
|
52
|
-
|
53
|
-
time = time[1..-1] if time.start_with?('+')
|
58
|
+
time.delete!('+')
|
54
59
|
match = time.match(/^(-?\d*\.?\d*)([smhdwy])$/)
|
55
60
|
(match[1].to_f * time_multiplier(match[2]) * m).to_i
|
56
|
-
|
57
|
-
|
61
|
+
end
|
62
|
+
|
63
|
+
# Is a relative time valid?
|
64
|
+
# @param time [String] time as +1d, -1h etc
|
65
|
+
# @return [Bool]
|
66
|
+
#
|
67
|
+
def valid_relative_time?(time)
|
68
|
+
time =~ /^[+-](-?\d*\.?\d*)[smhdwy]$/
|
58
69
|
end
|
59
70
|
|
60
71
|
# naively return the number of seconds from the given
|