wavefront-sdk 1.6.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/HISTORY.md +39 -13
- data/README.md +75 -28
- data/Rakefile +1 -1
- data/lib/wavefront-sdk/alert.rb +113 -17
- data/lib/wavefront-sdk/cloudintegration.rb +8 -8
- data/lib/wavefront-sdk/core/api.rb +99 -0
- data/lib/wavefront-sdk/core/api_caller.rb +211 -0
- data/lib/wavefront-sdk/{exception.rb → core/exception.rb} +11 -6
- data/lib/wavefront-sdk/{logger.rb → core/logger.rb} +2 -3
- data/lib/wavefront-sdk/{response.rb → core/response.rb} +69 -52
- data/lib/wavefront-sdk/credentials.rb +6 -3
- data/lib/wavefront-sdk/dashboard.rb +14 -14
- data/lib/wavefront-sdk/{constants.rb → defs/constants.rb} +1 -0
- data/lib/wavefront-sdk/defs/version.rb +1 -0
- data/lib/wavefront-sdk/derivedmetric.rb +14 -14
- data/lib/wavefront-sdk/distribution.rb +75 -0
- data/lib/wavefront-sdk/event.rb +13 -13
- data/lib/wavefront-sdk/externallink.rb +8 -8
- data/lib/wavefront-sdk/integration.rb +9 -9
- data/lib/wavefront-sdk/maintenancewindow.rb +54 -8
- data/lib/wavefront-sdk/message.rb +4 -4
- data/lib/wavefront-sdk/metric.rb +3 -3
- data/lib/wavefront-sdk/notificant.rb +9 -9
- data/lib/wavefront-sdk/paginator/base.rb +148 -0
- data/lib/wavefront-sdk/paginator/delete.rb +11 -0
- data/lib/wavefront-sdk/paginator/get.rb +11 -0
- data/lib/wavefront-sdk/paginator/post.rb +64 -0
- data/lib/wavefront-sdk/paginator/put.rb +11 -0
- data/lib/wavefront-sdk/proxy.rb +7 -7
- data/lib/wavefront-sdk/query.rb +4 -4
- data/lib/wavefront-sdk/report.rb +9 -25
- data/lib/wavefront-sdk/savedsearch.rb +8 -8
- data/lib/wavefront-sdk/search.rb +16 -13
- data/lib/wavefront-sdk/source.rb +14 -14
- data/lib/wavefront-sdk/{mixins.rb → support/mixins.rb} +8 -2
- data/lib/wavefront-sdk/{parse_time.rb → support/parse_time.rb} +2 -0
- data/lib/wavefront-sdk/types/status.rb +52 -0
- data/lib/wavefront-sdk/user.rb +8 -8
- data/lib/wavefront-sdk/validators.rb +52 -3
- data/lib/wavefront-sdk/webhook.rb +8 -8
- data/lib/wavefront-sdk/write.rb +153 -52
- data/lib/wavefront-sdk/writers/api.rb +38 -0
- data/lib/wavefront-sdk/writers/core.rb +146 -0
- data/lib/wavefront-sdk/writers/http.rb +42 -0
- data/lib/wavefront-sdk/writers/socket.rb +66 -0
- data/lib/wavefront-sdk/writers/summary.rb +39 -0
- data/lib/wavefront_sdk.rb +9 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/wavefront-sdk/alert_spec.rb +6 -0
- data/spec/wavefront-sdk/{base_spec.rb → core/api_caller_spec.rb} +28 -41
- data/spec/wavefront-sdk/core/api_spec.rb +31 -0
- data/spec/wavefront-sdk/{logger_spec.rb → core/logger_spec.rb} +3 -3
- data/spec/wavefront-sdk/core/response_spec.rb +77 -0
- data/spec/wavefront-sdk/credentials_spec.rb +15 -10
- data/spec/wavefront-sdk/distribution_spec.rb +78 -0
- data/spec/wavefront-sdk/paginator/base_spec.rb +67 -0
- data/spec/wavefront-sdk/paginator/post_spec.rb +53 -0
- data/spec/wavefront-sdk/report_spec.rb +3 -1
- data/spec/wavefront-sdk/search_spec.rb +25 -0
- data/spec/wavefront-sdk/stdlib/array_spec.rb +2 -1
- data/spec/wavefront-sdk/stdlib/hash_spec.rb +6 -1
- data/spec/wavefront-sdk/stdlib/string_spec.rb +2 -0
- data/spec/wavefront-sdk/{mixins_spec.rb → support/mixins_spec.rb} +2 -2
- data/spec/wavefront-sdk/{parse_time_spec.rb → support/parse_time_spec.rb} +2 -2
- data/spec/wavefront-sdk/validators_spec.rb +64 -1
- data/spec/wavefront-sdk/write_spec.rb +55 -77
- data/spec/wavefront-sdk/writers/api_spec.rb +45 -0
- data/spec/wavefront-sdk/writers/core_spec.rb +49 -0
- data/spec/wavefront-sdk/writers/http_spec.rb +69 -0
- data/spec/wavefront-sdk/writers/socket_spec.rb +104 -0
- data/spec/wavefront-sdk/writers/summary_spec.rb +38 -0
- data/wavefront-sdk.gemspec +1 -1
- metadata +52 -24
- data/lib/wavefront-sdk/base.rb +0 -264
- data/lib/wavefront-sdk/base_write.rb +0 -185
- data/lib/wavefront-sdk/stdlib.rb +0 -5
- data/lib/wavefront-sdk/version.rb +0 -1
- data/spec/wavefront-sdk/base_write_spec.rb +0 -82
- data/spec/wavefront-sdk/response_spec.rb +0 -39
@@ -1,185 +0,0 @@
|
|
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, opts)
|
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
|
-
def valid_point?(point)
|
129
|
-
return true if opts[:novalidate]
|
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
|
140
|
-
end
|
141
|
-
|
142
|
-
# Convert a validated point to a string conforming to
|
143
|
-
# https://community.wavefront.com/docs/DOC-1031. No validation
|
144
|
-
# is done here.
|
145
|
-
#
|
146
|
-
# @param point [Hash] a hash describing a point. See #write() for
|
147
|
-
# the format.
|
148
|
-
#
|
149
|
-
def hash_to_wf(point)
|
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
|
155
|
-
|
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]
|
168
|
-
end
|
169
|
-
|
170
|
-
# Wrapper for #really_send_point(), which really sends points.
|
171
|
-
#
|
172
|
-
# @param point [String] a point description, probably from
|
173
|
-
# #hash_to_wf()
|
174
|
-
#
|
175
|
-
def send_point(point)
|
176
|
-
if opts[:noop]
|
177
|
-
log "Would send: #{point}"
|
178
|
-
return
|
179
|
-
end
|
180
|
-
|
181
|
-
log("Sending: #{point}", :debug)
|
182
|
-
really_send_point(point)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
data/lib/wavefront-sdk/stdlib.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
WF_SDK_VERSION = '1.6.2'.freeze
|
@@ -1,82 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require_relative '../../lib/wavefront-sdk/base_write.rb'
|
4
|
-
require_relative '../spec_helper'
|
5
|
-
require_relative 'resources/dummy_points'
|
6
|
-
|
7
|
-
# rubocop:disable Style/MutableConstant
|
8
|
-
WBWT_CREDS = { endpoint: 'stub.wavefront.com', token: 'tkn' }
|
9
|
-
# rubocop:enable Style/MutableConstant
|
10
|
-
|
11
|
-
class WavefrontBaseWriteTest < MiniTest::Test
|
12
|
-
attr_reader :wf, :wf_tags
|
13
|
-
|
14
|
-
def setup
|
15
|
-
@wf = Wavefront::BaseWrite.new(WBWT_CREDS)
|
16
|
-
# @wf_noop = Wavefront::Write.new(W_CREDS, noop: true)
|
17
|
-
@wf_tags = Wavefront::BaseWrite.new(WBWT_CREDS, tags: TAGS)
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_summary_string
|
21
|
-
assert_equal('OK', wf.summary_string(unsent: 0, rejected: 0))
|
22
|
-
assert_equal('ERROR', wf.summary_string(unsent: 0, rejected: 1))
|
23
|
-
assert_equal('ERROR', wf.summary_string(unsent: 1, rejected: 0))
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_prepped_points
|
27
|
-
assert_equal wf.prepped_points(%w[p1 p2 p3 p4]), %w[p1 p2 p3 p4]
|
28
|
-
assert_equal wf.prepped_points([%w[p1 p2 p3 p4]]), %w[p1 p2 p3 p4]
|
29
|
-
assert_equal wf.prepped_points('p1'), %w[p1]
|
30
|
-
assert_equal wf.prepped_points(
|
31
|
-
[{ path: 'p1' }, { path: 'p2' }, { path: 'p3' }], 'prefix'
|
32
|
-
),
|
33
|
-
[{ path: 'prefix.p1' }, { path: 'prefix.p2' },
|
34
|
-
{ path: 'prefix.p3' }]
|
35
|
-
|
36
|
-
assert_equal wf.prepped_points({ path: 'p1' }, 'prefix'),
|
37
|
-
[{ path: 'prefix.p1' }]
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_paths_to_deltas
|
41
|
-
x = wf.paths_to_deltas(POINTS.dup)
|
42
|
-
assert_equal(x.size, 2)
|
43
|
-
|
44
|
-
x.each do |p|
|
45
|
-
assert_instance_of(Hash, p)
|
46
|
-
assert(p[:path].start_with?(DELTA))
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_hash_to_wf
|
51
|
-
assert_equal(wf.hash_to_wf(POINT),
|
52
|
-
'test.metric 123456 1469987572 ' \
|
53
|
-
'source=testhost t1="v1" t2="v2"')
|
54
|
-
assert_equal(wf_tags.hash_to_wf(POINT),
|
55
|
-
'test.metric 123456 1469987572 ' \
|
56
|
-
'source=testhost t1="v1" t2="v2" ' \
|
57
|
-
'gt1="gv1" gt2="gv2"')
|
58
|
-
|
59
|
-
p1 = POINT.dup
|
60
|
-
p1.delete(:ts)
|
61
|
-
assert_equal(wf.hash_to_wf(p1),
|
62
|
-
'test.metric 123456 source=testhost t1="v1" t2="v2"')
|
63
|
-
|
64
|
-
p2 = POINT.dup
|
65
|
-
p2.delete(:tags)
|
66
|
-
assert_equal(wf.hash_to_wf(p2),
|
67
|
-
'test.metric 123456 1469987572 source=testhost')
|
68
|
-
|
69
|
-
%i[value path].each do |k|
|
70
|
-
p3 = POINT.dup
|
71
|
-
p3.delete(k)
|
72
|
-
|
73
|
-
assert_raises(Wavefront::Exception::InvalidPoint) do
|
74
|
-
wf.hash_to_wf(p3)
|
75
|
-
end
|
76
|
-
|
77
|
-
assert_raises(Wavefront::Exception::InvalidPoint) do
|
78
|
-
wf_tags.hash_to_wf(p3)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
require_relative '../spec_helper'
|
4
|
-
require_relative '../../lib/wavefront-sdk/exception'
|
5
|
-
require_relative '../../lib/wavefront-sdk/response'
|
6
|
-
|
7
|
-
WF_JSON = '{"status":{"result":"OK","message":"","code":200},' \
|
8
|
-
'"response":{"items":[{"name":"test agent"}],"offset":0,' \
|
9
|
-
'"limit":100,"totalItems":3,"moreItems":false}}'.freeze
|
10
|
-
|
11
|
-
# Unit tests for Response class
|
12
|
-
#
|
13
|
-
class WavefrontResponseTest < MiniTest::Test
|
14
|
-
def test_initialize_good_data
|
15
|
-
wf = Wavefront::Response.new(WF_JSON, 200)
|
16
|
-
assert_instance_of(Wavefront::Response, wf)
|
17
|
-
assert_respond_to(wf, :status)
|
18
|
-
assert_respond_to(wf, :response)
|
19
|
-
assert_respond_to(wf.response, :items)
|
20
|
-
refute_respond_to(wf, :to_a)
|
21
|
-
%i[code message result].each { |m| assert_respond_to(wf.status, m) }
|
22
|
-
assert_equal(wf.status.code, 200)
|
23
|
-
assert_instance_of(Array, wf.response.items)
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_initialize_bad_data; end
|
27
|
-
|
28
|
-
def test_build_response
|
29
|
-
wf = Wavefront::Response.new(WF_JSON, 200)
|
30
|
-
assert_equal(Map.new, wf.build_response({}))
|
31
|
-
assert_equal(Map.new, wf.build_response([]))
|
32
|
-
assert_equal(Map.new, wf.build_response('string'))
|
33
|
-
assert_equal(Map.new(key: 123), wf.build_response(key: 123))
|
34
|
-
assert_equal(123, wf.build_response(response: 123))
|
35
|
-
assert_equal([1, 2], wf.build_response(response: [1, 2]))
|
36
|
-
assert_equal(Map.new(key: 123),
|
37
|
-
wf.build_response(response: { key: 123 }))
|
38
|
-
end
|
39
|
-
end
|