wavefront-sdk 1.6.2 → 2.0.0

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.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/HISTORY.md +39 -13
  4. data/README.md +75 -28
  5. data/Rakefile +1 -1
  6. data/lib/wavefront-sdk/alert.rb +113 -17
  7. data/lib/wavefront-sdk/cloudintegration.rb +8 -8
  8. data/lib/wavefront-sdk/core/api.rb +99 -0
  9. data/lib/wavefront-sdk/core/api_caller.rb +211 -0
  10. data/lib/wavefront-sdk/{exception.rb → core/exception.rb} +11 -6
  11. data/lib/wavefront-sdk/{logger.rb → core/logger.rb} +2 -3
  12. data/lib/wavefront-sdk/{response.rb → core/response.rb} +69 -52
  13. data/lib/wavefront-sdk/credentials.rb +6 -3
  14. data/lib/wavefront-sdk/dashboard.rb +14 -14
  15. data/lib/wavefront-sdk/{constants.rb → defs/constants.rb} +1 -0
  16. data/lib/wavefront-sdk/defs/version.rb +1 -0
  17. data/lib/wavefront-sdk/derivedmetric.rb +14 -14
  18. data/lib/wavefront-sdk/distribution.rb +75 -0
  19. data/lib/wavefront-sdk/event.rb +13 -13
  20. data/lib/wavefront-sdk/externallink.rb +8 -8
  21. data/lib/wavefront-sdk/integration.rb +9 -9
  22. data/lib/wavefront-sdk/maintenancewindow.rb +54 -8
  23. data/lib/wavefront-sdk/message.rb +4 -4
  24. data/lib/wavefront-sdk/metric.rb +3 -3
  25. data/lib/wavefront-sdk/notificant.rb +9 -9
  26. data/lib/wavefront-sdk/paginator/base.rb +148 -0
  27. data/lib/wavefront-sdk/paginator/delete.rb +11 -0
  28. data/lib/wavefront-sdk/paginator/get.rb +11 -0
  29. data/lib/wavefront-sdk/paginator/post.rb +64 -0
  30. data/lib/wavefront-sdk/paginator/put.rb +11 -0
  31. data/lib/wavefront-sdk/proxy.rb +7 -7
  32. data/lib/wavefront-sdk/query.rb +4 -4
  33. data/lib/wavefront-sdk/report.rb +9 -25
  34. data/lib/wavefront-sdk/savedsearch.rb +8 -8
  35. data/lib/wavefront-sdk/search.rb +16 -13
  36. data/lib/wavefront-sdk/source.rb +14 -14
  37. data/lib/wavefront-sdk/{mixins.rb → support/mixins.rb} +8 -2
  38. data/lib/wavefront-sdk/{parse_time.rb → support/parse_time.rb} +2 -0
  39. data/lib/wavefront-sdk/types/status.rb +52 -0
  40. data/lib/wavefront-sdk/user.rb +8 -8
  41. data/lib/wavefront-sdk/validators.rb +52 -3
  42. data/lib/wavefront-sdk/webhook.rb +8 -8
  43. data/lib/wavefront-sdk/write.rb +153 -52
  44. data/lib/wavefront-sdk/writers/api.rb +38 -0
  45. data/lib/wavefront-sdk/writers/core.rb +146 -0
  46. data/lib/wavefront-sdk/writers/http.rb +42 -0
  47. data/lib/wavefront-sdk/writers/socket.rb +66 -0
  48. data/lib/wavefront-sdk/writers/summary.rb +39 -0
  49. data/lib/wavefront_sdk.rb +9 -0
  50. data/spec/spec_helper.rb +3 -0
  51. data/spec/wavefront-sdk/alert_spec.rb +6 -0
  52. data/spec/wavefront-sdk/{base_spec.rb → core/api_caller_spec.rb} +28 -41
  53. data/spec/wavefront-sdk/core/api_spec.rb +31 -0
  54. data/spec/wavefront-sdk/{logger_spec.rb → core/logger_spec.rb} +3 -3
  55. data/spec/wavefront-sdk/core/response_spec.rb +77 -0
  56. data/spec/wavefront-sdk/credentials_spec.rb +15 -10
  57. data/spec/wavefront-sdk/distribution_spec.rb +78 -0
  58. data/spec/wavefront-sdk/paginator/base_spec.rb +67 -0
  59. data/spec/wavefront-sdk/paginator/post_spec.rb +53 -0
  60. data/spec/wavefront-sdk/report_spec.rb +3 -1
  61. data/spec/wavefront-sdk/search_spec.rb +25 -0
  62. data/spec/wavefront-sdk/stdlib/array_spec.rb +2 -1
  63. data/spec/wavefront-sdk/stdlib/hash_spec.rb +6 -1
  64. data/spec/wavefront-sdk/stdlib/string_spec.rb +2 -0
  65. data/spec/wavefront-sdk/{mixins_spec.rb → support/mixins_spec.rb} +2 -2
  66. data/spec/wavefront-sdk/{parse_time_spec.rb → support/parse_time_spec.rb} +2 -2
  67. data/spec/wavefront-sdk/validators_spec.rb +64 -1
  68. data/spec/wavefront-sdk/write_spec.rb +55 -77
  69. data/spec/wavefront-sdk/writers/api_spec.rb +45 -0
  70. data/spec/wavefront-sdk/writers/core_spec.rb +49 -0
  71. data/spec/wavefront-sdk/writers/http_spec.rb +69 -0
  72. data/spec/wavefront-sdk/writers/socket_spec.rb +104 -0
  73. data/spec/wavefront-sdk/writers/summary_spec.rb +38 -0
  74. data/wavefront-sdk.gemspec +1 -1
  75. metadata +52 -24
  76. data/lib/wavefront-sdk/base.rb +0 -264
  77. data/lib/wavefront-sdk/base_write.rb +0 -185
  78. data/lib/wavefront-sdk/stdlib.rb +0 -5
  79. data/lib/wavefront-sdk/version.rb +0 -1
  80. data/spec/wavefront-sdk/base_write_spec.rb +0 -82
  81. 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
@@ -1,5 +0,0 @@
1
- require 'pathname'
2
-
3
- (Pathname.new(__FILE__).dirname + 'stdlib').realpath.children.each do |f|
4
- require f if f.extname == '.rb'
5
- end
@@ -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