fluent-plugin-cloudwatch-ingest-chaeyk 0.4.2 → 0.4.3

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
  SHA1:
3
- metadata.gz: 791d8ae3a09f23b29a3a0e9a0714e75556339f89
4
- data.tar.gz: 4837ba8d518e6f564b9a069e247fe21cc230ec8d
3
+ metadata.gz: b77c18e98f2c2b14518b200ae364ade70b76d8a9
4
+ data.tar.gz: 3eb03829d3d30b8a4427f15b96362391e401824a
5
5
  SHA512:
6
- metadata.gz: df7af18b9f6fd76e2161875092fb7ed88be58a65bc66a23aa2df34f2ce7ac979c40b93a61d850b4b5eb2d9228cdb03cb30c597660175da52d22d284d3dc02d7a
7
- data.tar.gz: 04777edff81450b15c3fb6eee7336af2dc5ce423137e7ff2db9d44030c0ac03dd7de34f686cc98ae7c138c2496bf5e7651f964acf54f4644259454c1828f4673
6
+ metadata.gz: 30c46498a01f39697ed3d24987fdd8fa1d90af203df91eaffccdb1154ce4758cea2d35cd84032d0f4a0ecc0f3c365ebddc5f76a2504247b3eab1d4864380782b
7
+ data.tar.gz: d0e0a05b240b24324875d29fd6dc8425ca7478aa26b9b879aec1840633315d45331cb398bf999cf3478deeff558a44549a2681b6f53a8403d60ac100688c74b6
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in fluent-plugin-cloudwatch-ingest-chaeyk.gemspec
3
+ # Specify your dependencies in fluent-plugin-cloudwatch-ingest-chaeyk.gemspec
4
4
  gemspec
@@ -6,7 +6,7 @@ require 'fluent/plugin/cloudwatch/ingest/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = 'fluent-plugin-cloudwatch-ingest-chaeyk'
9
- spec.version = Fluent::Plugin::Cloudwatch::Ingest::Chaeyk::VERSION
9
+ spec.version = Fluent::Plugin::Cloudwatch::Ingest::VERSION
10
10
  spec.authors = ['chaeyk']
11
11
  spec.email = ['chaeyk@gmail.com']
12
12
 
@@ -2,9 +2,7 @@ module Fluent
2
2
  module Plugin
3
3
  module Cloudwatch
4
4
  module Ingest
5
- module Chaeyk
6
- VERSION = '0.4.2'.freeze
7
- end
5
+ VERSION = '0.4.3'.freeze
8
6
  end
9
7
  end
10
8
  end
@@ -181,12 +181,55 @@ module Fluent::Plugin
181
181
  return log_streams
182
182
  end
183
183
 
184
+ def process_stream(group, stream, next_token, start_time, state)
185
+ event_count = 0
186
+
187
+ response = @aws.get_log_events(
188
+ log_group_name: group,
189
+ log_stream_name: stream,
190
+ next_token: next_token,
191
+ limit: @limit_events,
192
+ start_time: start_time,
193
+ start_from_head: @oldest_logs_first
194
+ )
195
+
196
+ response.events.each do |e|
197
+ begin
198
+ emit(e, group, stream)
199
+ event_count += 1
200
+ rescue => boom
201
+ log.error("Failed to emit event #{e}: #{boom.inspect}")
202
+ end
203
+ end
204
+
205
+ has_stream_timestamp = true if state.store[group][stream]['timestamp']
206
+
207
+ if !has_stream_timestamp && response.events.count.zero?
208
+ # This stream has returned no data ever.
209
+ # In this case, don't save state (token could be an invalid one)
210
+ else
211
+ # Once all events for this stream have been processed,
212
+ # in this iteration, store the forward token
213
+ state.new_store[group][stream]['token'] = response.next_forward_token
214
+ if response.events.last
215
+ state.new_store[group][stream]['timestamp'] =
216
+ response.events.last.timestamp
217
+ else
218
+ state.new_store[group][stream]['timestamp'] =
219
+ state.store[group][stream]['timestamp']
220
+ end
221
+ end
222
+
223
+ return event_count
224
+ end
225
+
184
226
  def run
185
227
  until @finished
186
228
  begin
187
229
  state = State.new(@state_file_name, log)
188
230
  rescue => boom
189
- log.info("Failed lock state. Sleeping for #{@interval}: #{boom.inspect}")
231
+ log.info("Failed lock state. Sleeping for #{@interval}: "\
232
+ "#{boom.inspect}")
190
233
  sleep @interval
191
234
  next
192
235
  end
@@ -197,96 +240,45 @@ module Fluent::Plugin
197
240
  log_groups(@log_group_name_prefix).each do |group|
198
241
  # For each log stream get and emit the events
199
242
  log_streams(group, @log_stream_name_prefix).each do |stream|
200
- if ! state.store[group][stream]
201
- state.store[group][stream] = {}
202
- end
243
+ state.store[group][stream] = {} unless state.store[group][stream]
244
+
245
+ log.info("processing stream: #{stream}")
203
246
 
204
247
  # See if we have some stored state for this group and stream.
205
248
  # If we have then use the stored forward_token to pick up
206
249
  # from that point. Otherwise start from the start.
207
- if state.store[group][stream]['token']
208
- stream_token = state.store[group][stream]['token']
209
- else
210
- stream_token = nil
211
- end
212
-
213
- if state.store[group][stream]['timestamp']
214
- stream_timestamp = state.store[group][stream]['timestamp']
215
- else
216
- stream_timestamp = @event_start_time
217
- end
218
250
 
219
251
  begin
220
- response = @aws.get_log_events(
221
- log_group_name: group,
222
- log_stream_name: stream,
223
- next_token: stream_token,
224
- limit: @limit_events,
225
- start_time: @event_start_time,
226
- start_from_head: @oldest_logs_first
227
- )
228
-
229
- response.events.each do |e|
230
- begin
231
- emit(e, group, stream)
232
- event_count = event_count + 1
233
- rescue => boom
234
- log.error("Failed to emit event #{e}: #{boom.inspect}")
235
- end
236
- end
237
-
238
- # Once all events for this stream have been processed,
239
- # in this iteration, store the forward token
240
- log.info("stream: #{stream} token: #{stream_token} count: #{event_count}")
241
- if stream_token or response.events.count > 0
242
- log.info("saving: #{response.events}")
243
- state.store[group][stream]['token'] = response.next_forward_token
244
- state.store[group][stream]['timestamp'] = response.events.last ? response.events.last.timestamp : stream_timestamp
245
- else
246
- log.info("throw out")
247
- state.store[group].delete(stream)
248
- end
249
- rescue Aws::CloudWatchLogs::Errors::InvalidParameterException => boom
250
- log.error("cloudwatch token is expired or broken. trying with timestamp.");
252
+ event_count += process_stream(group, stream,
253
+ state.store[group][stream]['token'],
254
+ @event_start_time, state)
255
+ rescue Aws::CloudWatchLogs::Errors::InvalidParameterException
256
+ log.error('cloudwatch token is expired or broken. '\
257
+ 'trying with timestamp.')
251
258
 
252
259
  # try again with timestamp instead of forward token
253
260
  begin
254
- response = @aws.get_log_events(
255
- log_group_name: group,
256
- log_stream_name: stream,
257
- limit: @limit_events,
258
- start_time: stream_timestamp,
259
- start_from_head: true
260
- )
261
-
262
- response.events.each do |e|
263
- begin
264
- emit(e, group, stream)
265
- event_count = event_count + 1
266
- rescue => boom
267
- log.error("Failed to emit event #{e}: #{boom.inspect}")
268
- end
269
- end
270
-
271
- # Once all events for this stream have been processed,
272
- # in this iteration, store the forward token
273
- state.store[group][stream]["token"] = response.next_forward_token
274
- state.store[group][stream]['timestamp'] = response.events.last ? response.events.last.timestamp : steam_timestamp
261
+ timestamp = state.store[group][stream]['timestamp']
262
+ timestamp = @event_start_time unless timestamp
263
+
264
+ event_count += process_stream(group, stream,
265
+ nil, timestamp, state)
275
266
  rescue => boom
276
- log.error("Unable to retrieve events for stream #{stream} in group #{group}: #{boom.inspect}") # rubocop:disable all
267
+ log.error("Unable to retrieve events for stream #{stream} "\
268
+ "in group #{group}: #{boom.inspect}") # rubocop:disable all
277
269
  sleep @api_interval
278
270
  next
279
271
  end
280
272
  rescue => boom
281
- log.error("Unable to retrieve events for stream #{stream} in group #{group}: #{boom.inspect}") # rubocop:disable all
273
+ log.error("Unable to retrieve events for stream #{stream} "\
274
+ "in group #{group}: #{boom.inspect}") # rubocop:disable all
282
275
  sleep @api_interval
283
276
  next
284
277
  end
285
278
  end
286
279
  end
287
280
 
288
- log.info('Pruning and saving state')
289
- state.prune(log_groups(@log_group_name_prefix)) # Remove dead streams
281
+ log.info('Saving state')
290
282
  begin
291
283
  state.save
292
284
  state.close
@@ -308,12 +300,13 @@ module Fluent::Plugin
308
300
 
309
301
  class CloudwatchIngestInput::State
310
302
  class LockFailed < RuntimeError; end
311
- attr_accessor :statefile, :store
303
+ attr_accessor :statefile, :store, :new_store
312
304
 
313
305
  def initialize(filepath, log)
314
306
  @filepath = filepath
315
307
  @log = log
316
- @store = Hash.new { |h, k| h[k] = Hash.new { |h1, k1| h1[k1] = {} } }
308
+ @store = Hash.new { |h, k| h[k] = Hash.new { |x, y| x[y] = {} } }
309
+ @new_store = Hash.new { |h, k| h[k] = Hash.new { |x, y| x[y] = {} } }
317
310
 
318
311
  if File.exist?(filepath)
319
312
  self.statefile = Pathname.new(@filepath).open('r+')
@@ -323,7 +316,8 @@ module Fluent::Plugin
323
316
  self.statefile = Pathname.new(@filepath).open('w+')
324
317
  save
325
318
  rescue => boom
326
- @log.error("Unable to create new file #{statefile.path}: #{boom.inspect}")
319
+ @log.error("Unable to create new file #{statefile.path}: "\
320
+ "#{boom.inspect}")
327
321
  end
328
322
  end
329
323
 
@@ -337,11 +331,14 @@ module Fluent::Plugin
337
331
  @store.merge!(Psych.safe_load(statefile.read))
338
332
 
339
333
  # Migrate old state file
340
- @store.each { |group, streams|
341
- streams.update(streams) { |name, stream|
342
- (stream.is_a? String) ? { 'token' => stream, 'timestamp' => Time.now.to_i } : stream
343
- }
344
- }
334
+ @store.each do |_group, streams|
335
+ streams.update(streams) do |_name, stream|
336
+ if stream.is_a? String
337
+ return { 'token' => stream, 'timestamp' => Time.now.to_i }
338
+ end
339
+ return stream
340
+ end
341
+ end
345
342
 
346
343
  @log.info("Loaded #{@store.keys.size} groups from #{statefile.path}")
347
344
  rescue
@@ -353,7 +350,7 @@ module Fluent::Plugin
353
350
  def save
354
351
  statefile.rewind
355
352
  statefile.truncate(0)
356
- statefile.write(Psych.dump(@store))
353
+ statefile.write(Psych.dump(@new_store))
357
354
  @log.info("Saved state to #{statefile.path}")
358
355
  statefile.rewind
359
356
  end
@@ -361,14 +358,6 @@ module Fluent::Plugin
361
358
  def close
362
359
  statefile.close
363
360
  end
364
-
365
- def prune(log_groups)
366
- groups_before = @store.keys.size
367
- @store.delete_if { |k, _v| true unless log_groups.include?(k) }
368
- @log.info("Pruned #{groups_before - @store.keys.size} keys from store")
369
-
370
- # TODO: also prune streams as these are most likely to be transient
371
- end
372
361
  end
373
362
  end
374
363
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-cloudwatch-ingest-chaeyk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - chaeyk
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-30 00:00:00.000000000 Z
11
+ date: 2017-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler