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.
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