logstash-output-dynatrace 0.7.0 → 0.7.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4db961537a03cb5b21240ab63ea56877ceebcf0a075c5db85feb736b787d05df
4
- data.tar.gz: 185005382c4ac576fde60eeffa8d3f1a5e037445b3dd92b2126be22f0a3481dc
3
+ metadata.gz: 6dc320145268685ae7585b0ffc68beb54ae932b3e9c5261e1ca6106803c487df
4
+ data.tar.gz: 223b65b82ffc6ed512d270eb879126a9f9fbe046f9dfc9e66ae9a37be2e60fcf
5
5
  SHA512:
6
- metadata.gz: 0b14e9eba2edf866eff03c2fa7333ec23733bb6622dd841fcc3da9ddf5cfe5e5b1104238a2857cadc7474bc49444773ee0b5ae7cabcbbaddbefd28e4da403bb8
7
- data.tar.gz: 334f37197001b662b86c451c1dcb1faa059f94d1d4045ad43e66590f08663e7a90ea5979bbe247d3d2d7774a0f0e386d6f97c33663e6bef70c0dc6b909557ce3
6
+ metadata.gz: 55a4b11c59aae913134c5972dff31b13c3e3eaa8761db6703a88e081df6d369b39d6be5f924219e30312b819a54c30d7aced19d98b24f6bcf4e988561929ce50
7
+ data.tar.gz: 401c4c51154584cee22c94f557a5869b8782759b5287498571e2f1ae345150f48625417126140bb54676560a3d75f7659b30ca392b2db2470dae7815b49904d2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.7.2
2
+
3
+ - Log response bodies when the response is `200` indicating the request was only partially accepted
4
+
5
+ ## 0.7.1
6
+
7
+ - Fix an error where max payload size was calculated using character count instead of bytes
8
+
1
9
  ## 0.7.0
2
10
 
3
11
  - Add new development dependency `rackup` for logstash 8.x compatibility
@@ -122,11 +122,11 @@ module LogStash
122
122
 
123
123
  def offer(serialized_event)
124
124
  # 2 square brackets, the length of all previously serialized strings, commas, and the current event size
125
- batch_size_bytes = 2 + @batch_events_size + @serialized_events.length + serialized_event.length
125
+ batch_size_bytes = 2 + @batch_events_size + @serialized_events.length + serialized_event.bytesize
126
126
  return false if batch_size_bytes > @max_batch_size
127
127
 
128
128
  @serialized_events.push(serialized_event)
129
- @batch_events_size += serialized_event.length
129
+ @batch_events_size += serialized_event.bytesize
130
130
  true
131
131
  end
132
132
 
@@ -160,6 +160,10 @@ module LogStash
160
160
  end
161
161
  end
162
162
 
163
+ def log_partial_success_response(response)
164
+ @logger.warn("Encountered partial success response", code: response.code, body: response.body)
165
+ end
166
+
163
167
  def log_error_response(response, ingest_endpoint_url, event)
164
168
  log_failure(
165
169
  "Encountered non-2xx HTTP code #{response.code}",
@@ -178,8 +182,8 @@ module LogStash
178
182
 
179
183
  events.each do |event|
180
184
  serialized_event = LogStash::Json.dump(event.to_hash)
181
- if serialized_event.length > @max_payload_size
182
- log_params = { size: serialized_event.length }
185
+ if serialized_event.bytesize > @max_payload_size
186
+ log_params = { size: serialized_event.bytesize }
183
187
  log_params[:body] = serialized_event if @debug_include_body
184
188
  log_warning('Event larger than max_payload_size dropped', log_params)
185
189
  next
@@ -267,6 +271,8 @@ module LogStash
267
271
  response = client.post(ingest_endpoint_url, body: event, headers: headers)
268
272
 
269
273
  if response_success?(response)
274
+ # some events were not accepted but we don't know which ones or why
275
+ log_partial_success_response(response) if response_partial_success?(response)
270
276
  [:success, event, attempt]
271
277
  elsif retryable_response?(response)
272
278
  log_retryable_response(response)
@@ -315,6 +321,10 @@ module LogStash
315
321
  response.code >= 200 && response.code <= 299
316
322
  end
317
323
 
324
+ def response_partial_success?(response)
325
+ response.code == 200
326
+ end
327
+
318
328
  def retryable_response?(response)
319
329
  RETRYABLE_CODES.include?(response.code)
320
330
  end
@@ -168,6 +168,19 @@ describe LogStash::Outputs::Dynatrace do
168
168
  end
169
169
  end
170
170
 
171
+ context 'with partial success responses' do
172
+ let(:ingest_endpoint_url) { "http://localhost:#{port}/partial" }
173
+
174
+ before do
175
+ allow(subject).to receive(:log_partial_success_response)
176
+ end
177
+
178
+ it 'should warn on partial success' do
179
+ subject.multi_receive([event])
180
+ expect(subject).to have_received(:log_partial_success_response)
181
+ end
182
+ end
183
+
171
184
  context 'with retryable failing requests' do
172
185
  let(:ingest_endpoint_url) { "http://localhost:#{port}/retry" }
173
186
  let(:api_key) { 'placeholder-key' }
@@ -232,17 +245,38 @@ describe LogStash::Outputs::Dynatrace do
232
245
  end
233
246
  end
234
247
 
235
- context 'max_payload_size 2MB' do
236
- let(:config) { { 'ingest_endpoint_url' => ingest_endpoint_url, 'api_key' => api_key, 'max_payload_size' => 2_000_000 } }
248
+ context 'max_payload_size 500' do
249
+ let(:max_payload_size) { 500 }
250
+ let(:config) { { 'ingest_endpoint_url' => ingest_endpoint_url, 'api_key' => api_key, 'max_payload_size' => max_payload_size } }
237
251
  subject { LogStash::Outputs::Dynatrace.new(config) }
238
252
 
239
253
  before do
240
254
  allow(subject).to receive(:send_event) { |e, att| [:success, e, att] }
241
- subject.multi_receive([1, 2].map { |n| LogStash::Event.new({ 'n' => n.to_s * 1_250_000 }) })
242
255
  end
243
256
 
244
- it 'should split the chunk into multiple requests' do
245
- expect(subject).to have_received(:send_event).exactly(2).times
257
+ it 'should send 2 400B messages in multiple requests' do
258
+ subject.multi_receive([1, 2].map { |n| LogStash::Event.new({ 'n' => n.to_s * 400 }) })
259
+ expect(subject).to have_received(:send_event).exactly(2).times do |s|
260
+ expect(s.bytesize).to be <= max_payload_size
261
+ end
262
+ end
263
+
264
+ it 'should send 2 100B messages in a single request' do
265
+ subject.multi_receive([1, 2].map { |n| LogStash::Event.new({ 'n' => n.to_s * 100 }) })
266
+ expect(subject).to have_received(:send_event).exactly(1).times do |s|
267
+ expect(s.bytesize).to be <= max_payload_size
268
+ end
269
+ end
270
+
271
+ it 'should drop messages larger than max_payload_size' do
272
+ subject.multi_receive([
273
+ LogStash::Event.new({ 'event' => '🤣' * 400 }),
274
+ LogStash::Event.new({ 'event' => 'n' * 600 }),
275
+ LogStash::Event.new({ 'event' => 'n' * 400 }),
276
+ ])
277
+ expect(subject).to have_received(:send_event).exactly(1).times do |s|
278
+ expect(s.bytesize).to be <= max_payload_size
279
+ end
246
280
  end
247
281
  end
248
282
 
data/spec/spec_helper.rb CHANGED
@@ -98,7 +98,12 @@ class TestApp < Sinatra::Base
98
98
 
99
99
  multiroute(%w[get post put patch delete], '/good') do
100
100
  self.class.last_request = request
101
- [200, 'YUP']
101
+ [204, 'YUP']
102
+ end
103
+
104
+ multiroute(%w[get post put patch delete], '/partial') do
105
+ self.class.last_request = request
106
+ [200, 'partial success']
102
107
  end
103
108
 
104
109
  multiroute(%w[get post put patch delete], '/bad') do
data/version.yaml CHANGED
@@ -1 +1 @@
1
- logstash-output-dynatrace: '0.7.0'
1
+ logstash-output-dynatrace: '0.7.2'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-dynatrace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dynatrace Open Source Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-08 00:00:00.000000000 Z
11
+ date: 2025-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-codec-json