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

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: 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.