wavefront-sdk 1.6.0 → 1.6.1

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: e68e0e9c6233a7fb449408c84111beaf522c023370188d155c234aa3387c411c
4
- data.tar.gz: 0a3575ed176110827a011b6793b1d6f3cf8eb64e96dba1ce4b2f129ef1234219
3
+ metadata.gz: e599fd70e3a67cdc62c8ec942382db101850582e8bd98c11e8e56e18a1d1bfaf
4
+ data.tar.gz: 134f436ff650ba75a4cad1e93bcf229ea25787dbafa5fcf40aa93b067bed9402
5
5
  SHA512:
6
- metadata.gz: 47af2cca2a5ca29d545aefb936e3850234e117d53d6ee46580b931e505fda6fdb446004680102631b1b19d463889cf601d6578de27b0e7358094b498a24174ee
7
- data.tar.gz: 736e992312831e5c1b2f37558c70cfec883950eab7f82777baa1c9a2ba3848b0adc0abc20972d27f70e34fbe77ce027b850b65bc6781c55e78cc50a6edbfa294
6
+ metadata.gz: 3f051f1594d486c3b6c65ed964a0e2b822a034975a19ad9745926048e891ce5a8f89a063a17532ff8a90b3b1c89085ba448d57346dff33b6300765bd3f365b3e
7
+ data.tar.gz: 0a97bf0ed08c8ee08607b4e98f55cc5daeb7b30e6245df99407c0dddfb708ed093bbaeb3d9aaac805d09da12ca61cccdd94c96222458545bc7857d536d43002e
@@ -1,8 +1,15 @@
1
+ ---
1
2
  AllCops:
2
- TargetRubyVersion: 2.3
3
+ TargetRubyVersion: 2.2
3
4
 
4
5
  Style/FrozenStringLiteralComment:
5
6
  Enabled: false
6
7
 
7
- Lint/MissingCopEnableDirective:
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
@@ -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, :update_keys,
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 = opts
48
- @debug = opts[:debug] || false
49
- @noop = opts[:noop] || false
47
+ @opts = opts
48
+ @debug = opts[:debug] || false
49
+ @noop = opts[:noop] || false
50
50
  @verbose = opts[:verbose] || false
51
- @logger = opts[:logger] || nil
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
- Faraday.new(
89
- url: Addressable::URI.encode("https://#{net[:endpoint]}" +
90
- [net[:api_base], path].uri_concat),
91
- headers: net[:headers].merge(headers)
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
- # #noop class variable is set. If #verbose is set, then prints
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
- # #noop class variable is set. If #verbose is set, then prints
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
- # #noop class variable is set. If #verbose is set, then prints
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
- # #noop class variable is set. If #verbose is set, then prints
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, debug)
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 "uri: #{method.upcase} #{conn.url_prefix}"
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
- puts log method == :get ? "params: #{args.last}" : "body: #{args.last}"
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 setup_endpoint(creds)
242
+ def validate_credentials(creds)
265
243
  %w[endpoint token].each do |k|
266
- raise "creds must contain #{k}" unless creds.key?(k.to_sym)
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
- 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
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
- unless point.key?(:path) && point.key?(:value)
158
- raise Wavefront::Exception::InvalidPoint
159
- end
160
-
161
- point[:source] = HOSTNAME unless point.key?(:source)
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
- 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(' ')
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.
@@ -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 = parse_time(to, true)
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
- api_get('', { earliestStartTimeEpochMillis: from,
36
- latestStartTimeEpochMillis: to,
37
- cursor: cursor, limit: limit }.select { |_k, v| v })
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
@@ -3,6 +3,7 @@ module Wavefront
3
3
  # Simple exception classes
4
4
  #
5
5
  class Exception
6
+ class CredentialError < RuntimeError; end
6
7
  class EmptyMetricName < RuntimeError; end
7
8
  class InvalidAlertId < RuntimeError; end
8
9
  class InvalidAlertSeverity < RuntimeError; end
@@ -10,7 +10,8 @@ module Wavefront
10
10
  end
11
11
 
12
12
  def update_keys
13
- %i[name template description]
13
+ %i[name template description metricFilterRegex sourceFilterRegex
14
+ pointTagFilterRegexes]
14
15
  end
15
16
 
16
17
  # GET /api/v2/extlink
@@ -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
@@ -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
- q = [[:m, metric]]
23
+ query = [[:m, metric]]
25
24
 
26
25
  if cursor
27
26
  raise ArgumentError unless cursor.is_a?(String)
28
- q.<< [:c, cursor]
27
+ query.<< [:c, cursor]
29
28
  end
30
29
 
31
- sources.each { |s| q.<< [:h, s] }
30
+ sources.each { |source| query.<< [:h, source] }
32
31
 
33
- api_get('detail', q)
32
+ api_get('detail', query)
34
33
  end
35
34
  end
36
35
  end
@@ -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 time.start_with?('+', '-')
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
- rescue NoMethodError
57
- raise Wavefront::Exception::InvalidRelativeTime
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