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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b77c18e98f2c2b14518b200ae364ade70b76d8a9
|
4
|
+
data.tar.gz: 3eb03829d3d30b8a4427f15b96362391e401824a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30c46498a01f39697ed3d24987fdd8fa1d90af203df91eaffccdb1154ce4758cea2d35cd84032d0f4a0ecc0f3c365ebddc5f76a2504247b3eab1d4864380782b
|
7
|
+
data.tar.gz: d0e0a05b240b24324875d29fd6dc8425ca7478aa26b9b879aec1840633315d45331cb398bf999cf3478deeff558a44549a2681b6f53a8403d60ac100688c74b6
|
data/Gemfile
CHANGED
@@ -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::
|
9
|
+
spec.version = Fluent::Plugin::Cloudwatch::Ingest::VERSION
|
10
10
|
spec.authors = ['chaeyk']
|
11
11
|
spec.email = ['chaeyk@gmail.com']
|
12
12
|
|
@@ -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}:
|
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
|
-
|
201
|
-
|
202
|
-
|
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
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
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
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
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}
|
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}
|
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('
|
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 { |
|
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}:
|
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
|
341
|
-
streams.update(streams)
|
342
|
-
|
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(@
|
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.
|
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
|
11
|
+
date: 2017-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|