fluent-plugin-rewrite-tag-filter 2.2.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8253bb2b1859438ea797e1fd2046d0b18290a424b340de8a88524b9afd33388a
4
- data.tar.gz: 33e91a5b0570810f2ad802885df4a7e87eb03c4816b5779d847c5004b25afb0a
3
+ metadata.gz: a12e8f6567cd07462a236f0cda38e98bac14b921a2c7b762e9851cb04e5bf119
4
+ data.tar.gz: b198b1e6b8a48d386f7cc62521f358cdff745754edc8dda753ac176ced1e3e67
5
5
  SHA512:
6
- metadata.gz: f28d04ee233a9bfdd668f5dc114b7e9b7d5531d275d1c5318100d4a76171607ddf9e03041081b139ba2f7a55b6b73bdbf64c44cae67097df983ae80395d04e69
7
- data.tar.gz: 4e6ee684e6da26e6d0e449cc0650dd482f9cbd5cd6623d540bb63b1b991e48f0ede38f9424f04ef8750e6d7f451afa62c89bda412e3bff66589b3101407414d3
6
+ metadata.gz: cc556895e92c3f53ca3c41af6866072e48ac53b6b170cfe163f1563d04310c8b89cc802cabefd957dab95da29362ff76164621f0a83d806619d67df521e866b6
7
+ data.tar.gz: 1777b76d00afe128f20da230ca26d0c30d4f62e60f4800efec6b59450040e54de7b861ee7913ed82af8f91b9f3cf5e11344b5ec5b08e57af97d611a0060d0ddf
data/.travis.yml CHANGED
@@ -1,10 +1,10 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.4.2
5
- - 2.3.5
6
- - 2.2
7
- - 2.1
4
+ - 2.7.0
5
+ - 2.6.5
6
+ - 2.5.7
7
+ - 2.4.9
8
8
 
9
9
  # to avoid travis-ci issue since 2015-12-25
10
10
  before_install:
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  ## Overview
4
4
 
5
5
  Rewrite Tag Filter for [Fluentd](http://fluentd.org). It is designed to rewrite tags like mod_rewrite.
6
- Re-emit the record with rewrited tag when a value matches/unmatches with a regular expression.
6
+ Re-emit the record with rewritten tag when a value matches/unmatches with a regular expression.
7
7
  Also you can change a tag from Apache log by domain, status code (ex. 500 error),
8
8
  user-agent, request-uri, regex-backreference and so on with regular expression.
9
9
 
@@ -31,7 +31,7 @@ $ sudo td-agent-gem install fluent-plugin-rewrite-tag-filter -v 1.6.0
31
31
  $ sudo td-agent-gem install fluent-plugin-rewrite-tag-filter
32
32
  ```
33
33
 
34
- For more details, see [Plugin Management](https://docs.fluentd.org/v0.14/articles/plugin-management)
34
+ For more details, see [Plugin Management](https://docs.fluentd.org/deployment/plugin-management)
35
35
 
36
36
  ## Configuration
37
37
 
@@ -52,6 +52,7 @@ For more details, see [Plugin Management](https://docs.fluentd.org/v0.14/article
52
52
  `/regexp/` is preferred because `/regexp/` style can support character classes such as `/[a-z]/`.
53
53
  The pattern without slashes will cause errors if you use patterns start with character classes.
54
54
  * **tag** (string) (required): New tag
55
+ * **label** (string) (optional): New label. If specified, label can be changed per-rule.
55
56
  * **invert** (bool) (optional): If true, rewrite tag when unmatch pattern
56
57
  * Default value: `false`
57
58
 
@@ -200,7 +201,7 @@ When original tag is `kubernetes.var.log`, this will be converted to `default.ku
200
201
 
201
202
  ### Tag placeholder
202
203
 
203
- It is supported these placeholder for new_tag (rewrited tag).
204
+ It is supported these placeholder for new_tag (rewritten tag).
204
205
 
205
206
  - `${tag}`
206
207
  - `__TAG__`
@@ -214,12 +215,16 @@ For example with `td.apache.access` tag, it will get `td` by `${tag_parts[0]}` a
214
215
 
215
216
  **Note** Currently, range expression ```${tag_parts[0..2]}``` is not supported.
216
217
 
217
- #### Placeholder Option
218
+ #### Placeholder Options
218
219
 
219
220
  * `remove_tag_prefix`
220
221
 
221
222
  This option adds removing tag prefix for `${tag}` or `__TAG__` in placeholder.
222
223
 
224
+ * `remove_tag_regexp`
225
+
226
+ This option adds removing tag regexp for `${tag}` or `__TAG__` in placeholder.
227
+
223
228
  * `hostname_command`
224
229
 
225
230
  By default, execute command as `hostname` to get full hostname.
@@ -231,49 +236,100 @@ It comes short hostname with `hostname_command hostname -s` configuration specif
231
236
  It's a sample to rewrite a tag with placeholder.
232
237
 
233
238
  ```
234
- # It will get "rewrited.access.ExampleMail"
239
+ # It will get "rewritten.access.ExampleMail"
235
240
  <match apache.access>
236
241
  @type rewrite_tag_filter
237
242
  remove_tag_prefix apache
238
243
  <rule>
239
244
  key domain
240
245
  pattern ^(mail)\.(example)\.com$
241
- tag rewrited.${tag}.$2$1
246
+ tag rewritten.${tag}.$2$1
247
+ </rule>
248
+ </match>
249
+
250
+ # It will get "rewritten.access.ExampleMail"
251
+ <match apache.access>
252
+ @type rewrite_tag_filter
253
+ remove_tag_regexp /^apache\./
254
+ <rule>
255
+ key domain
256
+ pattern ^(mail)\.(example)\.com$
257
+ tag rewritten.${tag}.$2$1
258
+ </rule>
259
+ </match>
260
+
261
+ # It will get "http.access.log"
262
+ <match input.{apache,nginx}.access.log>
263
+ @type rewrite_tag_filter
264
+ remove_tag_regexp /^input\.(apache|nginx)\./
265
+ <rule>
266
+ key domain
267
+ pattern ^.+$
268
+ tag http.${tag}
242
269
  </rule>
243
270
  </match>
244
271
 
245
- # It will get "rewrited.ExampleMail.app30-124.foo.com" when hostname is "app30-124.foo.com"
272
+ # It will get "rewritten.ExampleMail.app30-124.foo.com" when hostname is "app30-124.foo.com"
246
273
  <match apache.access>
247
274
  @type rewrite_tag_filter
248
275
  <rule>
249
276
  key domain
250
277
  pattern ^(mail)\.(example)\.com$
251
- tag rewrited.$2$1.${hostname}
278
+ tag rewritten.$2$1.${hostname}
252
279
  </rule>
253
280
  </match>
254
281
 
255
- # It will get "rewrited.ExampleMail.app30-124" when hostname is "app30-124.foo.com"
282
+ # It will get "rewritten.ExampleMail.app30-124" when hostname is "app30-124.foo.com"
256
283
  <match apache.access>
257
284
  @type rewrite_tag_filter
258
285
  hostname_command hostname -s
259
286
  <rule>
260
287
  key domain
261
288
  pattern ^(mail)\.(example)\.com$
262
- tag rewrited.$2$1.${hostname}
289
+ tag rewritten.$2$1.${hostname}
263
290
  </rule>
264
291
  </match>
265
292
 
266
- # It will get "rewrited.game.pool"
293
+ # It will get "rewritten.game.pool"
267
294
  <match app.game.pool.activity>
268
295
  @type rewrite_tag_filter
269
296
  <rule>
270
297
  key domain
271
298
  pattern ^.+$
272
- tag rewrited.${tag_parts[1]}.${tag_parts[2]}
299
+ tag rewritten.${tag_parts[1]}.${tag_parts[2]}
273
300
  </rule>
274
301
  </match>
275
302
  ```
276
303
 
304
+ ### Altering Labels
305
+
306
+ In addition to changing tags, you can also change event's route by setting
307
+ the label for the re-emitted event.
308
+
309
+ For example, given this configuration:
310
+
311
+ ```
312
+ <match apache.access>
313
+ @type rewrite_tag_filter
314
+ <rule>
315
+ key domain
316
+ pattern ^www\.example\.com$
317
+ tag web.${tag}
318
+ </rule>
319
+ <rule>
320
+ key domain
321
+ pattern ^(.*)\.example\.com$
322
+ tag other.$1
323
+ label other
324
+ </rule>
325
+ </match>
326
+ ```
327
+
328
+ message: `{"domain": "www.example.com"}` will get its tag changed to
329
+ `web.apache.access`, while message
330
+ `{"domain": "api.example.com"}` will get its tag changed to `other.api` and
331
+ be sent to label `other`
332
+
277
333
  ## Example
278
334
 
279
335
  - Example1: how to analyze response_time, response_code and user_agent for each virtual domain websites.
@@ -1,9 +1,8 @@
1
- # -*- encoding: utf-8 -*-
2
1
  $:.push File.expand_path("../lib", __FILE__)
3
2
 
4
3
  Gem::Specification.new do |s|
5
4
  s.name = "fluent-plugin-rewrite-tag-filter"
6
- s.version = "2.2.0"
5
+ s.version = "2.4.0"
7
6
  s.license = "Apache-2.0"
8
7
  s.authors = ["Kentaro Yoshida"]
9
8
  s.email = ["y.ken.studio@gmail.com"]
@@ -10,6 +10,8 @@ class Fluent::Plugin::RewriteTagFilterOutput < Fluent::Plugin::Output
10
10
  config_param :capitalize_regex_backreference, :bool, :default => false
11
11
  desc 'Remove tag prefix for tag placeholder.'
12
12
  config_param :remove_tag_prefix, :string, :default => nil
13
+ desc "Remove tag regexp for tag placeholder."
14
+ config_param :remove_tag_regexp, :regexp, default: nil
13
15
  desc 'Override hostname command for placeholder.'
14
16
  config_param :hostname_command, :string, :default => 'hostname'
15
17
  desc "The emit mode. If `batch`, this plugin will emit events per rewritten tag."
@@ -22,6 +24,8 @@ class Fluent::Plugin::RewriteTagFilterOutput < Fluent::Plugin::Output
22
24
  config_param :pattern, :regexp
23
25
  desc "New tag"
24
26
  config_param :tag, :string
27
+ desc "New label. If specified, label can be changed per-rule."
28
+ config_param :label, :string, default: nil
25
29
  desc "If true, rewrite tag when unmatch pattern"
26
30
  config_param :invert, :bool, default: false
27
31
  end
@@ -41,7 +45,7 @@ class Fluent::Plugin::RewriteTagFilterOutput < Fluent::Plugin::Output
41
45
  end
42
46
 
43
47
  invert = rule.invert ? MATCH_OPERATOR_EXCLUDE : ""
44
- @rewriterules.push([record_accessor_create(rule.key), rule.pattern, invert, rule.tag])
48
+ @rewriterules.push([record_accessor_create(rule.key), rule.pattern, invert, rule.tag, rule.label])
45
49
  rewriterule_names.push(rule.key + invert + rule.pattern.to_s)
46
50
  log.info "adding rewrite_tag_filter rule: #{rule.key} #{@rewriterules.last}"
47
51
  end
@@ -58,8 +62,12 @@ class Fluent::Plugin::RewriteTagFilterOutput < Fluent::Plugin::Output
58
62
  raise Fluent::ConfigError, "duplicated rewriterules found #{@rewriterules.inspect}"
59
63
  end
60
64
 
65
+ if @remove_tag_prefix && @remove_tag_regexp
66
+ raise Fluent::ConfigError, "remove_tag_prefix and remove_tag_regexp are exclusive"
67
+ end
68
+
61
69
  unless @remove_tag_prefix.nil?
62
- @remove_tag_prefix = /^#{Regexp.escape(@remove_tag_prefix)}\.?/
70
+ @remove_tag_regexp = /^#{Regexp.escape(@remove_tag_prefix)}\.?/
63
71
  end
64
72
 
65
73
  @batch_mode = @emit_mode == :batch
@@ -69,35 +77,45 @@ class Fluent::Plugin::RewriteTagFilterOutput < Fluent::Plugin::Output
69
77
  true
70
78
  end
71
79
 
80
+ def get_router(tgt_label)
81
+ label_router = if tgt_label.nil? || tgt_label.empty?
82
+ router
83
+ else
84
+ event_emitter_router(tgt_label)
85
+ end
86
+ #log.trace "Got router for #{tgt_label}: #{!label_router.nil?}"
87
+ return label_router
88
+ end
89
+
72
90
  def process(tag, es)
73
91
  placeholder = get_placeholder(tag)
74
- if @batch_mode
75
- new_event_streams = Hash.new {|h, k| h[k] = Fluent::MultiEventStream.new }
76
- es.each do |time, record|
77
- rewrited_tag = rewrite_tag(tag, record, placeholder)
78
- if rewrited_tag.nil? || tag == rewrited_tag
79
- log.trace("rewrite_tag_filter: tag has not been rewritten", record)
80
- next
81
- end
82
- new_event_streams[rewrited_tag].add(time, record)
92
+ new_event_streams = Hash.new {|hh, kk| hh[kk] = Hash.new {|h, k| h[k] = Fluent::MultiEventStream.new }}if @batch_mode
93
+
94
+ es.each do |time, record|
95
+ rewrited_tag, rewrited_label = rewrite_tag(tag, record, placeholder)
96
+ if (rewrited_tag.nil? || tag == rewrited_tag) && rewrited_label.nil?
97
+ log.trace("rewrite_tag_filter: tag has not been rewritten", record)
98
+ next
83
99
  end
84
- new_event_streams.each do |rewrited_tag, new_es|
85
- router.emit_stream(rewrited_tag, new_es)
100
+ rewrited_tag = tag if rewrited_tag.nil?
101
+ if new_event_streams.nil?
102
+ get_router(rewrited_label).emit(rewrited_tag, time, record)
103
+ else
104
+ new_event_streams[rewrited_label][rewrited_tag].add(time, record)
86
105
  end
87
- else
88
- es.each do |time, record|
89
- rewrited_tag = rewrite_tag(tag, record, placeholder)
90
- if rewrited_tag.nil? || tag == rewrited_tag
91
- log.trace("rewrite_tag_filter: tag has not been rewritten", record)
92
- next
106
+ end
107
+ if !new_event_streams.nil?
108
+ new_event_streams.each do |rewrited_label, label_event_streams |
109
+ labeled_router = get_router(rewrited_label)
110
+ label_event_streams.each do |rewrited_tag, new_es|
111
+ labeled_router.emit_stream(rewrited_tag, new_es)
93
112
  end
94
- router.emit(rewrited_tag, time, record)
95
113
  end
96
114
  end
97
115
  end
98
116
 
99
117
  def rewrite_tag(tag, record, placeholder)
100
- @rewriterules.each do |record_accessor, regexp, match_operator, rewritetag|
118
+ @rewriterules.each do |record_accessor, regexp, match_operator, rewritetag, rewritelabel|
101
119
  rewritevalue = record_accessor.call(record).to_s
102
120
  next if rewritevalue.empty? && match_operator != MATCH_OPERATOR_EXCLUDE
103
121
  last_match = regexp_last_match(regexp, rewritevalue)
@@ -113,9 +131,9 @@ class Fluent::Plugin::RewriteTagFilterOutput < Fluent::Plugin::Output
113
131
  log.warn "rewrite_tag_filter: unknown placeholder found. :placeholder=>#{$1} :tag=>#{tag} :rewritetag=>#{rewritetag}" unless placeholder.include?($1)
114
132
  placeholder[$1]
115
133
  end
116
- return rewritetag
134
+ return rewritetag, rewritelabel
117
135
  end
118
- return nil
136
+ return nil, nil
119
137
  end
120
138
 
121
139
  def regexp_last_match(regexp, rewritevalue)
@@ -135,7 +153,7 @@ class Fluent::Plugin::RewriteTagFilterOutput < Fluent::Plugin::Output
135
153
  end
136
154
 
137
155
  def get_placeholder(tag)
138
- tag = tag.sub(@remove_tag_prefix, '') if @remove_tag_prefix
156
+ tag = tag.sub(@remove_tag_regexp, '') if @remove_tag_regexp
139
157
 
140
158
  result = {
141
159
  '__HOSTNAME__' => @hostname,
@@ -41,6 +41,21 @@ class RewriteTagFilterOutputTest < Test::Unit::TestCase
41
41
  d = create_driver(conf)
42
42
  assert_equal(/.+/, d.instance.rules.first.pattern)
43
43
  end
44
+
45
+ test "remove_tag_prefix and remove_tag_regexp are exclusive" do
46
+ conf = %[
47
+ remove_tag_prefix prefix
48
+ remove_tag_regexp /^prefix\./
49
+ <rule>
50
+ key message
51
+ pattern .+
52
+ tag ${tag}
53
+ </rule>
54
+ ]
55
+ assert_raise(Fluent::ConfigError) do
56
+ create_driver(conf)
57
+ end
58
+ end
44
59
  end
45
60
 
46
61
  sub_test_case "section style" do
@@ -127,6 +142,30 @@ class RewriteTagFilterOutputTest < Test::Unit::TestCase
127
142
  assert_equal 'access', events[0][0] # tag
128
143
  end
129
144
 
145
+ sub_test_case "remove_tag_regexp" do
146
+ test "plain" do
147
+ config = %[
148
+ remove_tag_regexp /^input\.(apache|nginx)\./
149
+ <rule>
150
+ key domain
151
+ pattern ^www\.google\.com$
152
+ tag rewritten.${tag}
153
+ </rule>
154
+ ]
155
+ d = create_driver(config)
156
+ d.run do
157
+ d.feed('input.apache.access', event_time, {'domain' => 'www.google.com', 'path' => '/foo/bar?key=value', 'agent' => 'Googlebot', 'response_time' => 1000000})
158
+ d.feed('input.nginx.access', event_time, {'domain' => 'www.google.com', 'path' => '/foo/bar?key=value', 'agent' => 'Googlebot', 'response_time' => 1000000})
159
+ d.feed('input.tomcat.access', event_time, {'domain' => 'www.google.com', 'path' => '/foo/bar?key=value', 'agent' => 'Googlebot', 'response_time' => 1000000})
160
+ end
161
+ events = d.events
162
+ assert_equal 3, events.length
163
+ assert_equal 'rewritten.access', events[0][0]
164
+ assert_equal 'rewritten.access', events[1][0]
165
+ assert_equal 'rewritten.input.tomcat.access', events[2][0]
166
+ end
167
+ end
168
+
130
169
  test "short hostname" do
131
170
  config = %[
132
171
  remove_tag_prefix input
@@ -307,6 +346,77 @@ class RewriteTagFilterOutputTest < Test::Unit::TestCase
307
346
  assert_equal "com.example", events[0][0]
308
347
  end
309
348
 
349
+ test "get_router" do
350
+ conf = %[
351
+ <rule>
352
+ key key
353
+ pattern /^(odd|even)$/
354
+ tag $1
355
+ label new_label
356
+ </rule>
357
+ <rule>
358
+ key key
359
+ pattern /^(.*)$/
360
+ tag $1
361
+ </rule>
362
+ ]
363
+ time = event_time
364
+ d = create_driver(conf)
365
+ assert_equal(d.instance.router, d.instance.get_router(nil))
366
+ assert_equal(d.instance.router, d.instance.get_router(""))
367
+ new_label_router = d.instance.get_router("new_label")
368
+ refute_equal(d.instance.router, new_label_router)
369
+ end
370
+
371
+ test "relabel" do
372
+ conf = %[
373
+ emit_mode record
374
+ <rule>
375
+ key key
376
+ pattern /^(odd)$/
377
+ tag $1
378
+ label odd_label
379
+ </rule>
380
+ <rule>
381
+ key key
382
+ pattern /^(even)$/
383
+ tag ${tag}
384
+ label even_label
385
+ </rule>
386
+ <rule>
387
+ key key
388
+ pattern /^(.*)$/
389
+ tag $1
390
+ </rule>
391
+ ]
392
+ time = event_time
393
+ d = create_driver(conf)
394
+ # Router only called for default label
395
+ mock.proxy(d.instance.router).emit(anything, anything, anything).times(2)
396
+ mock.proxy(d.instance).get_router("odd_label").times(2)
397
+ mock.proxy(d.instance).get_router("even_label").times(2)
398
+ mock.proxy(d.instance).get_router(nil).times(2)
399
+ mock.proxy(d.instance.router).emit_stream(anything, anything).times(0)
400
+ d.run(default_tag: "input") do
401
+ d.feed([[time, { "key" => "odd", "message" => "message-1" }],
402
+ [time, { "key" => "even", "message" => "message-2" }],
403
+ [time, { "key" => "zero", "message" => "message-3" }],
404
+ [time, { "key" => "odd", "message" => "message-4" }],
405
+ [time, { "key" => "even", "message" => "message-5" }],
406
+ [time, { "key" => "zero", "message" => "message-6" }]])
407
+ end
408
+ events = d.events
409
+ expected_events = [
410
+ ["odd", time, { "key" => "odd", "message" => "message-1" }],
411
+ ["input", time, { "key" => "even", "message" => "message-2" }],
412
+ ["zero", time, { "key" => "zero", "message" => "message-3" }],
413
+ ["odd", time, { "key" => "odd", "message" => "message-4" }],
414
+ ["input", time, { "key" => "even", "message" => "message-5" }],
415
+ ["zero", time, { "key" => "zero", "message" => "message-6" }],
416
+ ]
417
+ assert_equal(events, expected_events)
418
+ end
419
+
310
420
  sub_test_case "emit_mode" do
311
421
  test "record" do
312
422
  conf = %[
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-rewrite-tag-filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kentaro Yoshida
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-12 00:00:00.000000000 Z
11
+ date: 2020-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  requirements: []
127
- rubygems_version: 3.0.1
127
+ rubygems_version: 3.1.4
128
128
  signing_key:
129
129
  specification_version: 4
130
130
  summary: Fluentd Output filter plugin. It has designed to rewrite tag like mod_rewrite.