fluent-plugin-elb-access-log 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: c7fc100990f59fc2792cbf0506b75ef400a1dd8f
4
- data.tar.gz: 9e6bda33e638700957ee92c685c699859eb4dfab
3
+ metadata.gz: 88a3b513a550db32f667fedc8ba75eea2e2f6199
4
+ data.tar.gz: 0e5dd5364065a98f38f15c54fe400e0826941ae4
5
5
  SHA512:
6
- metadata.gz: f280a3e9212f18ce0446daacd6fffb6d9d3e59413458e3f6052acd240523a5c2db8d42ea2d73ed53f90fbc51abe554edc13c73eca2414c65bd8661839c6579a5
7
- data.tar.gz: 26eb2f804a5245738cb6e7881ba3d454457ec3f575d8acc9d1b200da402f38a82eba0d263f0e42f4706dfeac18b3fcc62e50d40425c67b342c4cde93b5fa66e3
6
+ metadata.gz: 7c3c094dff47e82717c9cf8b80d2528f35257a61dc7bcb6c64c6943433e684082638c1e13256b43ea448b1e2e40487fbfcaa73353f8fb74245b739fc8e897edb
7
+ data.tar.gz: 8493ec02a57fb20f8fbaf144fa8930292b9658a90438b31a56d429b04a7690e72b4273d7a37de68422f721089181e02ecc9810a43bb271b7fea1bc5f61e8e806
data/README.md CHANGED
@@ -48,6 +48,10 @@ Or install it yourself as:
48
48
  #sampling_interval 1
49
49
  #debug false
50
50
  #elb_type clb # or alb
51
+ #filter elb_status_code:^2,timestamp:^2018
52
+ #filter_operator and # or "or"
53
+ #type_cast true
54
+ #parse_request true
51
55
  </source>
52
56
  ```
53
57
 
@@ -19,8 +19,8 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
19
19
  'clb' => {
20
20
  'timestamp' => nil,
21
21
  'elb' => nil,
22
- 'client_port' => nil,
23
- 'backend_port' => nil,
22
+ 'client_port' => :to_i,
23
+ 'backend_port' => :to_i,
24
24
  'request_processing_time' => :to_f,
25
25
  'backend_processing_time' => :to_f,
26
26
  'response_processing_time' => :to_f,
@@ -38,8 +38,8 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
38
38
  'type' => nil,
39
39
  'timestamp' => nil,
40
40
  'elb' => nil,
41
- 'client_port' => nil,
42
- 'target_port' => nil,
41
+ 'client_port' => :to_i,
42
+ 'target_port' => :to_i,
43
43
  'request_processing_time' => :to_f,
44
44
  'target_processing_time' => :to_f,
45
45
  'response_processing_time' => :to_f,
@@ -58,7 +58,7 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
58
58
  },
59
59
  }
60
60
 
61
- ELB_TYPES = %(clb alb)
61
+ ELB_TYPES = ACCESS_LOG_FIELDS.keys
62
62
 
63
63
  config_param :elb_type, :string, default: 'clb'
64
64
  config_param :aws_key_id, :string, default: nil, secret: true
@@ -79,12 +79,20 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
79
79
  config_param :history_length, :integer, default: 100
80
80
  config_param :sampling_interval, :integer, default: 1
81
81
  config_param :debug, :bool, default: false
82
+ config_param :filter, :hash, default: nil
83
+ config_param :filter_operator, :string, default: 'and'
84
+ config_param :type_cast, :bool, default: true
85
+ config_param :parse_request, :bool, default: true
82
86
 
83
87
  def configure(conf)
84
88
  super
85
89
 
86
90
  unless ELB_TYPES.include?(@elb_type)
87
- raise raise Fluent::ConfigError, "Invalid ELB type: #{@elb_type}"
91
+ raise Fluent::ConfigError, "Invalid ELB type: #{@elb_type}"
92
+ end
93
+
94
+ unless %w(and or).include?(@filter_operator)
95
+ raise Fluent::ConfigError, "Invalid filter operator: #{@filter_operator}"
88
96
  end
89
97
 
90
98
  FileUtils.touch(@tsfile_path)
@@ -102,6 +110,10 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
102
110
  end
103
111
 
104
112
  @history = load_history
113
+
114
+ if @filter
115
+ @filter = Hash[@filter.map {|k, v| [k.to_s, Regexp.new(v.to_s)] }]
116
+ end
105
117
  end
106
118
 
107
119
  def start
@@ -239,10 +251,6 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
239
251
  parsed_access_log.each do |row|
240
252
  record = Hash[access_log_fields.keys.zip(row)]
241
253
 
242
- access_log_fields.each do |name, conv|
243
- record[name] = record[name].send(conv) if conv
244
- end
245
-
246
254
  split_address_port!(record, 'client')
247
255
 
248
256
  case @elb_type
@@ -252,7 +260,23 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
252
260
  split_address_port!(record, 'target')
253
261
  end
254
262
 
255
- parse_request!(record)
263
+ if @filter
264
+ if @filter_operator == 'or'
265
+ next if @filter.all? {|k, r| record[k] !~ r }
266
+ else
267
+ next if @filter.any? {|k, r| record[k] !~ r }
268
+ end
269
+ end
270
+
271
+ if @type_cast
272
+ access_log_fields.each do |name, conv|
273
+ record[name] = record[name].send(conv) if conv
274
+ end
275
+ end
276
+
277
+ if @parse_request
278
+ parse_request!(record)
279
+ end
256
280
 
257
281
  records << record
258
282
  end
@@ -327,7 +351,7 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
327
351
  return unless address_port
328
352
  address, port = address_port.split(':', 2)
329
353
  record[prefix] = address
330
- record["#{prefix}_port"] = port.to_i
354
+ record["#{prefix}_port"] = port
331
355
  end
332
356
 
333
357
  def parse_request!(record)
@@ -344,7 +368,13 @@ class Fluent::Plugin::ElbAccessLogInput < Fluent::Input
344
368
 
345
369
  if uri
346
370
  [:scheme ,:user, :host, :port, :path, :query, :fragment].each do |key|
347
- record["request.uri.#{key}"] = uri.send(key)
371
+ value = uri.send(key)
372
+
373
+ if not @type_cast and key == :port
374
+ value = value.to_s
375
+ end
376
+
377
+ record["request.uri.#{key}"] = value
348
378
  end
349
379
  end
350
380
  rescue => e
@@ -1,3 +1,3 @@
1
1
  module FluentPluginElbAccessLog
2
- VERSION = '0.4.2'
2
+ VERSION = '0.4.3'
3
3
  end
@@ -275,6 +275,123 @@ https 2015-05-25T19:55:36.000000Z hoge 14.14.124.20:57673 10.0.199.184:80 0.0000
275
275
  is_expected.to match_table expected_emits
276
276
  end
277
277
  end
278
+
279
+ context 'with filter' do
280
+ let(:fluentd_conf) do
281
+ {
282
+ interval: 0,
283
+ account_id: account_id,
284
+ s3_bucket: s3_bucket,
285
+ region: region,
286
+ start_datetime: (today - 1).to_s,
287
+ elb_type: 'alb',
288
+ filter: '{"timestamp": "2015-05-25"}',
289
+ }
290
+ end
291
+
292
+ it do
293
+ expected_emits.slice!(0, 2)
294
+ is_expected.to match_table expected_emits
295
+ end
296
+ end
297
+
298
+ context 'with filter (or)' do
299
+ let(:fluentd_conf) do
300
+ {
301
+ interval: 0,
302
+ account_id: account_id,
303
+ s3_bucket: s3_bucket,
304
+ region: region,
305
+ start_datetime: (today - 1).to_s,
306
+ elb_type: 'alb',
307
+ filter: '{"timestamp": "2015-05-25"}',
308
+ filter_operator: 'or'
309
+ }
310
+ end
311
+
312
+ it do
313
+ expected_emits.slice!(0, 2)
314
+ is_expected.to match_table expected_emits
315
+ end
316
+ end
317
+
318
+ context 'with filter (or/multi)' do
319
+ let(:fluentd_conf) do
320
+ {
321
+ interval: 0,
322
+ account_id: account_id,
323
+ s3_bucket: s3_bucket,
324
+ region: region,
325
+ start_datetime: (today - 1).to_s,
326
+ elb_type: 'alb',
327
+ filter: '{"timestamp": "2015-05-25", "elb_status_code": "^2"}',
328
+ filter_operator: 'or'
329
+ }
330
+ end
331
+
332
+ it do
333
+ is_expected.to match_table expected_emits
334
+ end
335
+ end
336
+
337
+ context 'without type cast' do
338
+ let(:fluentd_conf) do
339
+ {
340
+ interval: 0,
341
+ account_id: account_id,
342
+ s3_bucket: s3_bucket,
343
+ region: region,
344
+ start_datetime: (today - 1).to_s,
345
+ elb_type: 'alb',
346
+ type_cast: 'false',
347
+ }
348
+ end
349
+
350
+ it do
351
+ expected_emits_without_type_cast = expected_emits.map do |tag, ts, h|
352
+ h = Hash[h.map {|k, v|
353
+ v = case v
354
+ when nil
355
+ v
356
+ when Float
357
+ "%.6f" % v
358
+ else
359
+ v.to_s
360
+ end
361
+
362
+ [k, v]
363
+ }]
364
+
365
+ [tag, ts, h]
366
+ end
367
+
368
+ is_expected.to match_table expected_emits_without_type_cast
369
+ end
370
+ end
371
+
372
+
373
+ context 'without request parsing' do
374
+ let(:fluentd_conf) do
375
+ {
376
+ interval: 0,
377
+ account_id: account_id,
378
+ s3_bucket: s3_bucket,
379
+ region: region,
380
+ start_datetime: (today - 1).to_s,
381
+ elb_type: 'alb',
382
+ parse_request: 'false',
383
+ }
384
+ end
385
+
386
+ it do
387
+ expected_emits_without_request_parsing = expected_emits.map do |tag, ts, h|
388
+ h = Hash[h.select {|k, v| k !~ /\Arequest\./ }]
389
+ [tag, ts, h]
390
+ end
391
+
392
+ is_expected.to match_table expected_emits_without_request_parsing
393
+ end
394
+ end
278
395
  end
279
396
 
280
397
  context 'when include bad URI' do
@@ -247,6 +247,117 @@ describe Fluent::Plugin::ElbAccessLogInput do
247
247
  is_expected.to match_table expected_emits
248
248
  end
249
249
  end
250
+
251
+ context 'with filter' do
252
+ let(:fluentd_conf) do
253
+ {
254
+ interval: 0,
255
+ account_id: account_id,
256
+ s3_bucket: s3_bucket,
257
+ region: region,
258
+ start_datetime: (today - 1).to_s,
259
+ filter: '{"timestamp": "2015-05-25"}',
260
+ }
261
+ end
262
+
263
+ it do
264
+ expected_emits.slice!(0, 2)
265
+ is_expected.to match_table expected_emits
266
+ end
267
+ end
268
+
269
+ context 'with filter (or)' do
270
+ let(:fluentd_conf) do
271
+ {
272
+ interval: 0,
273
+ account_id: account_id,
274
+ s3_bucket: s3_bucket,
275
+ region: region,
276
+ start_datetime: (today - 1).to_s,
277
+ filter: '{"timestamp": "2015-05-25"}',
278
+ filter_operator: 'or',
279
+ }
280
+ end
281
+
282
+ it do
283
+ expected_emits.slice!(0, 2)
284
+ is_expected.to match_table expected_emits
285
+ end
286
+ end
287
+
288
+ context 'with filter (or/multi)' do
289
+ let(:fluentd_conf) do
290
+ {
291
+ interval: 0,
292
+ account_id: account_id,
293
+ s3_bucket: s3_bucket,
294
+ region: region,
295
+ start_datetime: (today - 1).to_s,
296
+ filter: '{"timestamp": "2015-05-25", "elb_status_code": "^2"}',
297
+ filter_operator: 'or',
298
+ }
299
+ end
300
+
301
+ it do
302
+ is_expected.to match_table expected_emits
303
+ end
304
+ end
305
+
306
+ context 'without type cast' do
307
+ let(:fluentd_conf) do
308
+ {
309
+ interval: 0,
310
+ account_id: account_id,
311
+ s3_bucket: s3_bucket,
312
+ region: region,
313
+ start_datetime: (today - 1).to_s,
314
+ type_cast: 'false',
315
+ }
316
+ end
317
+
318
+ it do
319
+ expected_emits_without_type_cast = expected_emits.map do |tag, ts, h|
320
+ h = Hash[h.map {|k, v|
321
+ v = case v
322
+ when nil
323
+ v
324
+ when Float
325
+ "%.6f" % v
326
+ else
327
+ v.to_s
328
+ end
329
+
330
+ [k, v]
331
+ }]
332
+
333
+ [tag, ts, h]
334
+ end
335
+
336
+ is_expected.to match_table expected_emits_without_type_cast
337
+ end
338
+ end
339
+
340
+ context 'without request parsing' do
341
+ let(:fluentd_conf) do
342
+ {
343
+ interval: 0,
344
+ account_id: account_id,
345
+ s3_bucket: s3_bucket,
346
+ region: region,
347
+ start_datetime: (today - 1).to_s,
348
+ parse_request: 'false',
349
+ }
350
+ end
351
+
352
+ it do
353
+ expected_emits_without_request_parsing = expected_emits.map do |tag, ts, h|
354
+ h = Hash[h.select {|k, v| k !~ /\Arequest\./ }]
355
+ [tag, ts, h]
356
+ end
357
+
358
+ is_expected.to match_table expected_emits_without_request_parsing
359
+ end
360
+ end
250
361
  end
251
362
 
252
363
  context 'when include bad URI' do
@@ -44,6 +44,10 @@ describe 'Fluent::Plugin::ElbAccessLogInput#configure' do
44
44
  expect(driver.instance.sampling_interval).to eq 1
45
45
  expect(driver.instance.debug).to be_falsey
46
46
  expect(driver.instance.elb_type).to eq 'clb'
47
+ expect(driver.instance.filter).to be_nil
48
+ expect(driver.instance.filter_operator).to eq 'and'
49
+ expect(driver.instance.type_cast).to be_truthy
50
+ expect(driver.instance.parse_request).to be_truthy
47
51
  end
48
52
  end
49
53
 
@@ -63,6 +67,8 @@ describe 'Fluent::Plugin::ElbAccessLogInput#configure' do
63
67
  let(:history_length) { 200 }
64
68
  let(:sampling_interval) { 100 }
65
69
  let(:elb_type) { 'alb' }
70
+ let(:filter) { 'elb_status_code:^2' }
71
+ let(:filter_operator) { 'or' }
66
72
 
67
73
  let(:fluentd_conf) do
68
74
  {
@@ -85,6 +91,10 @@ describe 'Fluent::Plugin::ElbAccessLogInput#configure' do
85
91
  sampling_interval: sampling_interval,
86
92
  debug: true,
87
93
  elb_type: elb_type,
94
+ filter: filter,
95
+ filter_operator: filter_operator,
96
+ type_cast: 'false',
97
+ parse_request: 'false',
88
98
  }
89
99
  end
90
100
 
@@ -107,6 +117,10 @@ describe 'Fluent::Plugin::ElbAccessLogInput#configure' do
107
117
  expect(driver.instance.sampling_interval).to eq sampling_interval
108
118
  expect(driver.instance.debug).to be_truthy
109
119
  expect(driver.instance.elb_type).to eq elb_type
120
+ expect(driver.instance.filter).to eq('elb_status_code' => /^2/)
121
+ expect(driver.instance.filter_operator).to eq filter_operator
122
+ expect(driver.instance.type_cast).to be_falsey
123
+ expect(driver.instance.parse_request).to be_falsey
110
124
  end
111
125
  end
112
126
 
@@ -190,4 +204,24 @@ describe 'Fluent::Plugin::ElbAccessLogInput#configure' do
190
204
  }.to raise_error 'Invalid ELB type: invalid'
191
205
  end
192
206
  end
207
+
208
+ context 'when an invalid filter operator' do
209
+ let(:start_datetime) { '2015-01-01 01:02:03 UTC' }
210
+
211
+ let(:fluentd_conf) do
212
+ {
213
+ account_id: account_id,
214
+ s3_bucket: s3_bucket,
215
+ region: region,
216
+ start_datetime: start_datetime,
217
+ filter_operator: 'invalid',
218
+ }
219
+ end
220
+
221
+ it do
222
+ expect {
223
+ subject
224
+ }.to raise_error 'Invalid filter operator: invalid'
225
+ end
226
+ end
193
227
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-elb-access-log
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
  - Genki Sugawara
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-29 00:00:00.000000000 Z
11
+ date: 2018-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd