fluent-plugin-cloudwatch-logs 0.6.0 → 0.6.1

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: 4f4792d605b22ee6912e36c02a7e20037c91d9912bb68ae14dd3fbb49b7afa0b
4
- data.tar.gz: 445aa7b5656044ae51b54dbc86d6a0a6509682ae9cb273b19a1f4742d123ecb4
3
+ metadata.gz: f3809f992ae8d9967a7f1edae7ac40614496d98e38baf2d6aa18bcfbae5c72ff
4
+ data.tar.gz: 4eb7d7741fb3ef6e1c3d698f305c36ac49ee94df4d9350f5794a2e887e29984c
5
5
  SHA512:
6
- metadata.gz: 50726dbbe3b574499b65a54469afc04d13a2b82011253992bd662338bae1351106ab4a0e430f4f48537c8c7a8dc9866ec0fab264cba31373d1689dae5fc65082
7
- data.tar.gz: 8911874548680ac11cbf36c148c1dbe0e60b869d617d34b99711dbcbeb09e93aefac66e9e8e4ba4d3427bb45f42ac0d1fad3b103d2b3f3523172d331a648f39a
6
+ metadata.gz: 8da9d33a1217cae533af682e950314d5a0bd5dbaac8019f0309ef541f26434027ef4b0133bbf2e3030a87c685ba00839c766a99336b0dd0c9f1304a65698a647
7
+ data.tar.gz: a2df61af2a98d7dab6d2fb4b5aecbb904fd582aa80e9ae3dd4b15c00f8d320dface8b3fbfb8ba3b1cdf47641a8d4edce8e2e03eaf2eafc16ba976cf68edf9514
data/README.md CHANGED
@@ -132,6 +132,7 @@ Fetch sample log from CloudWatch Logs:
132
132
  * `aws_sts_role_arn`: the role ARN to assume when using cross-account sts authentication
133
133
  * `aws_sts_session_name`: the session name to use with sts authentication (default: `fluentd`)
134
134
  * `json_handler`: name of the library to be used to handle JSON data. For now, supported libraries are `json` (default) and `yajl`.
135
+ * `use_todays_log_stream`: use todays and yesterdays date as log stream name prefix (formatted YYYY/MM/DD). (default: `false`)
135
136
 
136
137
  This plugin uses [fluent-mixin-config-placeholders](https://github.com/tagomoris/fluent-mixin-config-placeholders) and you can use addtional variables such as %{hostname}, %{uuid}, etc. These variables are useful to put hostname in `log_stream_name`.
137
138
 
@@ -2,7 +2,7 @@ module Fluent
2
2
  module Plugin
3
3
  module Cloudwatch
4
4
  module Logs
5
- VERSION = "0.6.0"
5
+ VERSION = "0.6.1"
6
6
  end
7
7
  end
8
8
  end
@@ -1,3 +1,4 @@
1
+ require 'date'
1
2
  require 'fluent/plugin/input'
2
3
  require 'fluent/plugin/parser'
3
4
  require 'yajl'
@@ -17,12 +18,13 @@ module Fluent::Plugin
17
18
  config_param :endpoint, :string, :default => nil
18
19
  config_param :tag, :string
19
20
  config_param :log_group_name, :string
20
- config_param :log_stream_name, :string
21
+ config_param :log_stream_name, :string, :default => nil
21
22
  config_param :use_log_stream_name_prefix, :bool, default: false
22
23
  config_param :state_file, :string
23
24
  config_param :fetch_interval, :time, default: 60
24
25
  config_param :http_proxy, :string, default: nil
25
26
  config_param :json_handler, :enum, list: [:yajl, :json], :default => :yajl
27
+ config_param :use_todays_log_stream, :bool, default: false
26
28
 
27
29
  config_section :parse do
28
30
  config_set_default :@type, 'none'
@@ -105,8 +107,10 @@ module Fluent::Plugin
105
107
  if Time.now > @next_fetch_time
106
108
  @next_fetch_time += @fetch_interval
107
109
 
108
- if @use_log_stream_name_prefix
109
- log_streams = describe_log_streams
110
+ if @use_log_stream_name_prefix || @use_todays_log_stream
111
+ log_stream_name_prefix = @use_todays_log_stream ? get_todays_date : @log_stream_name
112
+ log_streams = describe_log_streams(log_stream_name_prefix)
113
+ log_streams.concat(describe_log_streams(get_yesterdays_date)) if @use_todays_log_stream
110
114
  log_streams.each do |log_stream|
111
115
  log_stream_name = log_stream.log_stream_name
112
116
  events = get_events(log_stream_name)
@@ -142,19 +146,22 @@ module Fluent::Plugin
142
146
  log_group_name: @log_group_name,
143
147
  log_stream_name: log_stream_name
144
148
  }
145
- request[:next_token] = next_token(log_stream_name) if next_token(log_stream_name)
149
+ log_next_token = next_token(log_stream_name)
150
+ request[:next_token] = log_next_token if !log_next_token.nil? && !log_next_token.empty?
146
151
  response = @logs.get_log_events(request)
147
- store_next_token(response.next_forward_token, log_stream_name)
152
+ if valid_next_token(log_next_token, response.next_forward_token)
153
+ store_next_token(response.next_forward_token, log_stream_name)
154
+ end
148
155
 
149
156
  response.events
150
157
  end
151
158
 
152
- def describe_log_streams(log_streams = nil, next_token = nil)
159
+ def describe_log_streams(log_stream_name_prefix, log_streams = nil, next_token = nil)
153
160
  request = {
154
161
  log_group_name: @log_group_name
155
162
  }
156
163
  request[:next_token] = next_token if next_token
157
- request[:log_stream_name_prefix] = @log_stream_name
164
+ request[:log_stream_name_prefix] = log_stream_name_prefix
158
165
  response = @logs.describe_log_streams(request)
159
166
  if log_streams
160
167
  log_streams.concat(response.log_streams)
@@ -162,9 +169,21 @@ module Fluent::Plugin
162
169
  log_streams = response.log_streams
163
170
  end
164
171
  if response.next_token
165
- log_streams = describe_log_streams(log_streams, response.next_token)
172
+ log_streams = describe_log_streams(log_stream_name_prefix, log_streams, response.next_token)
166
173
  end
167
174
  log_streams
168
175
  end
176
+
177
+ def valid_next_token(prev_token, next_token)
178
+ return prev_token != next_token.chomp && !next_token.nil?
179
+ end
180
+
181
+ def get_todays_date
182
+ return Date.today.strftime("%Y/%m/%d")
183
+ end
184
+
185
+ def get_yesterdays_date
186
+ return (Date.today - 1).strftime("%Y/%m/%d")
187
+ end
169
188
  end
170
189
  end
@@ -343,6 +343,7 @@ module Fluent::Plugin
343
343
  "log_stream" => stream_name,
344
344
  "new_sequence_token" => token,
345
345
  }
346
+ retry_count += 1
346
347
  rescue Aws::CloudWatchLogs::Errors::ResourceNotFoundException => err
347
348
  if @auto_create_stream && err.message == 'The specified log stream does not exist.'
348
349
  log.warn 'Creating log stream because "The specified log stream does not exist." error is got', {
@@ -352,6 +353,7 @@ module Fluent::Plugin
352
353
  }
353
354
  create_log_stream(group_name, stream_name)
354
355
  delete_sequence_token(group_name, stream_name)
356
+ retry_count += 1
355
357
  else
356
358
  raise err
357
359
  end
@@ -1,6 +1,7 @@
1
1
  require 'test_helper'
2
2
  require 'fluent/test/driver/input'
3
3
  require 'fluent/test/helpers'
4
+ require 'date'
4
5
 
5
6
  class CloudwatchLogsInputTest < Test::Unit::TestCase
6
7
  include CloudwatchLogsTestHelper
@@ -137,6 +138,87 @@ class CloudwatchLogsInputTest < Test::Unit::TestCase
137
138
  assert_true(emits.include? ['test', ((time_ms + 4000) / 1000).floor, {'cloudwatch' => 'logs4'}])
138
139
  end
139
140
 
141
+ def test_emit_with_todays_log_stream
142
+ new_log_stream("testprefix")
143
+ create_log_stream
144
+
145
+ today = DateTime.now.strftime("%Y/%m/%d")
146
+ yesterday = (Date.today - 1).strftime("%Y/%m/%d")
147
+ tomorrow = (Date.today + 1).strftime("%Y/%m/%d")
148
+
149
+
150
+ time_ms = (Time.now.to_f * 1000).floor
151
+ put_log_events([
152
+ {timestamp: time_ms + 1000, message: '{"cloudwatch":"logs1"}'},
153
+ {timestamp: time_ms + 2000, message: '{"cloudwatch":"logs2"}'},
154
+ ])
155
+
156
+ new_log_stream(today)
157
+ create_log_stream
158
+ put_log_events([
159
+ {timestamp: time_ms + 3000, message: '{"cloudwatch":"logs3"}'},
160
+ {timestamp: time_ms + 4000, message: '{"cloudwatch":"logs4"}'},
161
+ ])
162
+
163
+ new_log_stream(yesterday)
164
+ create_log_stream
165
+ put_log_events([
166
+ {timestamp: time_ms + 5000, message: '{"cloudwatch":"logs5"}'},
167
+ {timestamp: time_ms + 6000, message: '{"cloudwatch":"logs6"}'},
168
+ ])
169
+
170
+ new_log_stream(tomorrow)
171
+ create_log_stream
172
+ put_log_events([
173
+ {timestamp: time_ms + 7000, message: '{"cloudwatch":"logs7"}'},
174
+ {timestamp: time_ms + 8000, message: '{"cloudwatch":"logs8"}'},
175
+ ])
176
+
177
+ new_log_stream(today)
178
+ create_log_stream
179
+ put_log_events([
180
+ {timestamp: time_ms + 9000, message: '{"cloudwatch":"logs9"}'},
181
+ {timestamp: time_ms + 10000, message: '{"cloudwatch":"logs10"}'},
182
+ ])
183
+
184
+ new_log_stream(yesterday)
185
+ create_log_stream
186
+ put_log_events([
187
+ {timestamp: time_ms + 11000, message: '{"cloudwatch":"logs11"}'},
188
+ {timestamp: time_ms + 12000, message: '{"cloudwatch":"logs12"}'},
189
+ ])
190
+
191
+ sleep 15
192
+
193
+ d = create_driver(<<-EOC)
194
+ tag test
195
+ @type cloudwatch_logs
196
+ log_group_name #{log_group_name}
197
+ use_todays_log_stream true
198
+ state_file /tmp/state
199
+ #{aws_key_id}
200
+ #{aws_sec_key}
201
+ #{region}
202
+ #{endpoint}
203
+ EOC
204
+ d.run(expect_emits: 8, timeout: 15)
205
+
206
+ emits = d.events
207
+ assert_equal(8, emits.size)
208
+ assert_false(emits.include? ['test', ((time_ms + 1000) / 1000).floor, {'cloudwatch' => 'logs1'}])
209
+ assert_false(emits.include? ['test', ((time_ms + 2000) / 1000).floor, {'cloudwatch' => 'logs2'}])
210
+ assert_true(emits.include? ['test', ((time_ms + 3000) / 1000).floor, {'cloudwatch' => 'logs3'}])
211
+ assert_true(emits.include? ['test', ((time_ms + 4000) / 1000).floor, {'cloudwatch' => 'logs4'}])
212
+ assert_true(emits.include? ['test', ((time_ms + 5000) / 1000).floor, {'cloudwatch' => 'logs5'}])
213
+ assert_true(emits.include? ['test', ((time_ms + 6000) / 1000).floor, {'cloudwatch' => 'logs6'}])
214
+ assert_false(emits.include? ['test', ((time_ms + 7000) / 1000).floor, {'cloudwatch' => 'logs7'}])
215
+ assert_false(emits.include? ['test', ((time_ms + 8000) / 1000).floor, {'cloudwatch' => 'logs8'}])
216
+ assert_true(emits.include? ['test', ((time_ms + 9000) / 1000).floor, {'cloudwatch' => 'logs9'}])
217
+ assert_true(emits.include? ['test', ((time_ms + 10000) / 1000).floor, {'cloudwatch' => 'logs10'}])
218
+ assert_true(emits.include? ['test', ((time_ms + 11000) / 1000).floor, {'cloudwatch' => 'logs11'}])
219
+ assert_true(emits.include? ['test', ((time_ms + 12000) / 1000).floor, {'cloudwatch' => 'logs12'}])
220
+ end
221
+
140
222
  private
141
223
  def default_config
142
224
  <<-EOC
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-cloudwatch-logs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryota Arai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-11 00:00:00.000000000 Z
11
+ date: 2018-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd