fluent-mixin-rewrite-tag-name 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,14 +2,192 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- Fluentd mixin plugin to rewrite tag like [rewrite-tag-filter](https://github.com/fluent/fluent-plugin-rewrite-tag-filter) for your any plugins.
5
+ Fluentd mixin plugin to provides placeholder function for rewriting tag for your any plugins as like [fluent-plugin-rewrite-tag-filter](https://github.com/fluent/fluent-plugin-rewrite-tag-filter). It will let you get easy to implement tag placeholder for your own plugins.
6
+
7
+ ## Placeholders
8
+
9
+ It supportes these placeholder for rewriting tag.
10
+
11
+ - `${tag}`
12
+ - `__TAG__`
13
+ - `{$tag_parts[n]}`
14
+ - `__TAG_PARTS[n]__`
15
+ - `${hostname}`
16
+ - `__HOSTNAME__`
17
+
18
+ The placeholder of `{$tag_parts[n]}` and `__TAG_PARTS[n]__` acts accessing the index which split the tag with "." (dot).
19
+ For example with `td.apache.access` tag, it will get `td` by `${tag_parts[0]}` and `apache` by `${tag_parts[1]}`.
20
+
21
+ **Note**
22
+
23
+ * To support upcase placeholder, set `enable_placeholder_upcase true` in configuration.
24
+ * To support hostname placeholder, set `enable_placeholder_upcase true` in configuration.
25
+ * Currently, range expression ```${tag_parts[0..2]}``` is not supported.
26
+
27
+ #### Placeholder Option
28
+
29
+ * `hostname_command`
30
+
31
+ By default, execute command as `hostname` to get full hostname.
32
+ On your needs, it could override hostname command using `hostname_command` option.
33
+ It comes short hostname with `hostname_command hostname -s` configuration specified.
34
+
35
+ ## Configuration
36
+
37
+ Adding this mixin plugin, it will enabled to use these placeholder in your plugins.
38
+
39
+ ```xml
40
+ # input plugin example
41
+ <source>
42
+ type foo_bar
43
+
44
+ # it will be rewrited to be 'customprefix.web10-222' when short hostname is 'web10-222'.
45
+ tag customprefix.${hostname}
46
+
47
+ # to use hostname placeholder, set 'enable_placeholder_hostname true'
48
+ enable_placeholder_hostname true
49
+ hostname_command hostname -s
50
+ </source>
51
+ ```
52
+
53
+ ```xml
54
+ # output plugin example
55
+ <match test.foo>
56
+ type foo_bar
57
+
58
+ # it will be rewrited to be 'customprefix.test.foo'.
59
+ tag customprefix.${tag}
60
+ </match>
61
+ ```
62
+
63
+ Another examples are written in [unit test](https://github.com/y-ken/fluent-mixin-rewrite-tag-name/blob/master/test/mixin/test_rewrite_tag_name.rb).
6
64
 
7
65
  ## Usage
8
66
 
9
- TODO
67
+ #### 1. edit gemspec
68
+
69
+ add dependency for .gemspec file like below. For more detail, see [gemspec example](https://github.com/y-ken/fluent-plugin-anonymizer/blob/master/fluent-plugin-anonymizer.gemspec)
70
+
71
+ ```ruby
72
+ spec.add_runtime_dependency "fluent-mixin-rewrite-tag-name"
73
+ ```
74
+
75
+ #### 2. activate fluent-mixin-rewrite-tag-name for your plugin
76
+
77
+ It is the instruction in the case of adding `fluent-plugin-foobar`.
78
+
79
+ ```
80
+ $ cd fluent-plugin-foobar
81
+ $ vim fluent-plugin-foobar.gemspec # edit gemspec
82
+ $ bundle install --path vendor/bundle # or just type `bundle install`
83
+ ```
84
+
85
+ #### 3. edit your plugin to implement
86
+
87
+ It is a quick guide to enable your plugin to use RewriteTagNameMixin.
88
+ The key points of implmentation is just four below.
89
+
90
+ * add `require 'fluent/mixin/rewrite_tag_name'` at the top of source
91
+ * in the case of output plugin, add `include Fluent::HandleTagNameMixin`
92
+ this is required if you will use 'remove_tag_prefix' option together
93
+ * add `include Fluent::Mixin::RewriteTagName` in class after HandleTagNameMixin
94
+ * add `emit_tag = tag.dup` and `filter_record(emit_tag, time, record)` before `Engine.emit`
95
+
96
+ ##### implement example for input plugin
97
+
98
+ ```ruby
99
+ require 'fluent/mixin/rewrite_tag_name'
100
+
101
+ module Fluent
102
+ class FooBarInput < Fluent::Input
103
+ Plugin.register_input('foo_bar', self)
104
+
105
+ # ...snip...
106
+
107
+ include Fluent::HandleTagNameMixin
108
+ include Fluent::Mixin::RewriteTagName
109
+ config_param :hostname_command, :string, :default => 'hostname'
110
+
111
+ # ...snip...
112
+
113
+ def configure(conf)
114
+ super
115
+
116
+ # ...snip...
117
+
118
+ # add a error handling
119
+ if ( !@tag && !@remove_tag_prefix && !@remove_tag_suffix && !@add_tag_prefix && !@add_tag_suffix )
120
+ raise Fluent::ConfigError, "foo_bar: missing remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix."
121
+ end
122
+ end
123
+
124
+ # ...snip...
125
+
126
+ def emit_message(tag, message)
127
+ emit_tag = tag.dup
128
+ filter_record(emit_tag, time, message)
129
+ Engine.emit(emit_tag, Engine.now, message)
130
+ end
131
+
132
+ # ...snip...
133
+
134
+ end
135
+ end
136
+ ```
137
+
138
+ ##### implement example for output plugin
139
+
140
+ ```ruby
141
+ require 'fluent/mixin/rewrite_tag_name'
142
+
143
+ class Fluent
144
+ class FooBarOutput < Fluent::Output
145
+ Fluent::Plugin.register_output('foo_bar', self)
146
+
147
+ include Fluent::Mixin::RewriteTagName
148
+ config_param :hostname_command, :string, :default => 'hostname'
149
+
150
+ # ...snip...
151
+
152
+ def configure(conf)
153
+ super
154
+
155
+ # ...snip...
156
+
157
+ # add a error handling
158
+ if ( !@tag && !@remove_tag_prefix && !@remove_tag_suffix && !@add_tag_prefix && !@add_tag_suffix )
159
+ raise Fluent::ConfigError, "foo_bar: missing remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix."
160
+ end
161
+ end
162
+
163
+ # ...snip...
164
+
165
+ def emit(tag, es, chain)
166
+ es.each do |time, record|
167
+ emit_tag = tag.dup
168
+ filter_record(emit_tag, time, record)
169
+ Fluent::Engine.emit(emit_tag, time, record)
170
+ end
171
+ chain.next
172
+ end
173
+
174
+ # ...snip...
175
+
176
+ end
177
+ end
178
+ ```
179
+
180
+ ## Case Study
181
+
182
+ These cool plugins are using this mixin!
183
+
184
+ * [fluent-plugin-anonymizer](https://github.com/y-ken/fluent-plugin-anonymizer/)
10
185
 
11
186
  ## TODO
12
187
 
188
+ * switchable tag template variable like 'tag', 'tag_format'
189
+ * support range tag_parts like [fluent-plugin-forest](https://github.com/tagomoris/fluent-plugin-forest/compare/v0.2.2...master)
190
+ * support tag_prefix and tag_suffix placeholder like [fluent-plugin-record-reformer](https://github.com/sonots/fluent-plugin-record-reformer)
13
191
  * merge into [fluentd/lib/fluent/mixin.rb](https://github.com/fluent/fluentd/blob/master/lib/fluent/mixin.rb) as RewriteTagNameMixin module.
14
192
 
15
193
  Pull requests are very welcome!!
@@ -4,10 +4,10 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "fluent-mixin-rewrite-tag-name"
7
- spec.version = "0.0.1"
7
+ spec.version = "0.0.2"
8
8
  spec.authors = ["Kentaro Yoshida"]
9
9
  spec.email = ["y.ken.studio@gmail.com"]
10
- spec.summary = %q{Fluentd mixin plugin to rewrite tag like rewrite-tag-filter for your any plugins.}
10
+ spec.summary = %q{Fluentd mixin plugin to provides placeholder function for rewriting tag for your any plugins as like fluent-plugin-rewrite-tag-filter. It will let you get easy to implement tag placeholder for your own plugins.}
11
11
  spec.homepage = "https://github.com/y-ken/fluent-mixin-rewrite-tag-name"
12
12
  spec.license = "Apache License, Version 2.0"
13
13
 
@@ -2,7 +2,33 @@ module Fluent
2
2
  module Mixin
3
3
  module RewriteTagName
4
4
  include RecordFilterMixin
5
- attr_accessor :tag
5
+ attr_accessor :tag, :hostname_command
6
+ attr_accessor :enable_placeholder_upcase, :enable_placeholder_hostname
7
+
8
+ DEFAULT_HOSTNAME_COMMAND = 'hostname'
9
+
10
+ def configure(conf)
11
+ super
12
+
13
+ @placeholder_expander = PlaceholderExpander.new
14
+
15
+ if enable_upcase = conf['enable_placeholder_upcase']
16
+ @enable_placeholder_upcase = enable_upcase
17
+ end
18
+ if @enable_placeholder_upcase
19
+ @placeholder_expander.enable_placeholder_upcase
20
+ end
21
+
22
+ if enable_hostname = conf['enable_placeholder_hostname']
23
+ @enable_placeholder_hostname = enable_hostname
24
+ end
25
+ if @enable_placeholder_hostname
26
+ hostname_command = @hostname_command || DEFAULT_HOSTNAME_COMMAND
27
+ hostname = `#{hostname_command}`.chomp
28
+ @placeholder_expander.enable_placeholder_hostname
29
+ @placeholder_expander.set_hostname(hostname)
30
+ end
31
+ end
6
32
 
7
33
  def filter_record(tag, time, record)
8
34
  super
@@ -12,16 +38,64 @@ module Fluent
12
38
  end
13
39
 
14
40
  def rewrite_tag!(tag)
15
- placeholder = {
16
- '${tag}' => tag,
17
- '__TAG__' => tag
18
- }
19
- emit_tag = @tag.gsub(/(\${[a-z_]+(\[[0-9]+\])?}|__[A-Z_]+__)/) do
20
- $log.warn "RewriteTagNameMixin: unknown placeholder found. :placeholder=>#{$1} :tag=>#{tag} :rewritetag=>#{rewritetag}" unless placeholder.include?($1)
21
- placeholder[$1]
22
- end
41
+
42
+ @placeholder_expander.set_tag(tag)
43
+ emit_tag = @placeholder_expander.expand(@tag)
23
44
  tag.gsub!(tag, emit_tag)
24
45
  end
46
+
47
+ class PlaceholderExpander
48
+ # referenced https://github.com/fluent/fluent-plugin-rewrite-tag-filter, thanks!
49
+ # referenced https://github.com/sonots/fluent-plugin-record-reformer, thanks!
50
+ attr_reader :placeholders
51
+
52
+ def initialize
53
+ @placeholders = {}
54
+ @enable_options = {
55
+ :hostname => false,
56
+ :upcase => false,
57
+ }
58
+ end
59
+
60
+ def expand(str)
61
+ str.gsub(/(\${[a-z_]+(\[-?[0-9]+\])?}|__[A-Z_]+(\[-?[0-9]+\])?__)/) {
62
+ $log.warn "RewriteTagNameMixin: unknown placeholder `#{$1}` found" unless @placeholders.include?($1)
63
+ @placeholders[$1]
64
+ }
65
+ end
66
+
67
+ def enable_placeholder_hostname
68
+ @enable_options[:hostname] = true
69
+ end
70
+
71
+ def enable_placeholder_upcase
72
+ @enable_options[:upcase] = true
73
+ end
74
+
75
+ def set_tag(value)
76
+ set_placeholder('tag', value)
77
+ set_tag_parts(value)
78
+ end
79
+
80
+ def set_hostname(value)
81
+ set_placeholder('hostname', value)
82
+ end
83
+
84
+ def set_tag_parts(tag)
85
+ tag_parts = tag.split('.')
86
+ size = tag_parts.size
87
+ tag_parts.each_with_index { |t, idx|
88
+ set_placeholder("tag_parts[#{idx}]", t)
89
+ set_placeholder("tag_parts[#{idx-size}]", t) # support tag_parts[-1]
90
+ }
91
+ end
92
+
93
+ private
94
+ def set_placeholder(key, value)
95
+ @placeholders.store("${#{key.downcase}}", value)
96
+ @placeholders.store("__#{key.upcase}__", value) if @enable_options[:upcase]
97
+ end
98
+ end
25
99
  end
26
100
  end
27
101
  end
@@ -37,6 +37,22 @@ class RewriteTagNameMixinTest < Test::Unit::TestCase
37
37
  assert_equal 'foo', emits[0][2]['message']
38
38
  end
39
39
 
40
+ def test_emit_upcase
41
+ d1 = create_driver(%[
42
+ tag rewrited.__TAG__
43
+ remove_tag_prefix input.
44
+ enable_placeholder_upcase true
45
+ ], 'input.access')
46
+ d1.run do
47
+ d1.emit({'message' => 'foo'})
48
+ end
49
+ emits = d1.emits
50
+ assert_equal 1, emits.length
51
+ p emits[0]
52
+ assert_equal 'rewrited.access', emits[0][0] # tag
53
+ assert_equal 'foo', emits[0][2]['message']
54
+ end
55
+
40
56
  def test_emit_with_HandleTagNameMixin
41
57
  d1 = create_driver(%[
42
58
  tag rewrited.${tag}
@@ -51,4 +67,77 @@ class RewriteTagNameMixinTest < Test::Unit::TestCase
51
67
  assert_equal 'rewrited.access', emits[0][0] # tag
52
68
  assert_equal 'foo', emits[0][2]['message']
53
69
  end
70
+
71
+ def test_emit_tag_parts
72
+ d1 = create_driver(%[
73
+ tag rewrited.${tag_parts[1]}
74
+ ], 'input.access.foo.bar')
75
+ d1.run do
76
+ d1.emit({'message' => 'foo'})
77
+ end
78
+ emits = d1.emits
79
+ assert_equal 1, emits.length
80
+ p emits[0]
81
+ assert_equal 'rewrited.access', emits[0][0] # tag
82
+ end
83
+
84
+ def test_emit_tag_parts_negative
85
+ d1 = create_driver(%[
86
+ tag rewrited.${tag_parts[-1]}
87
+ ], 'input.access.foo.bar')
88
+ d1.run do
89
+ d1.emit({'message' => 'foo'})
90
+ end
91
+ emits = d1.emits
92
+ assert_equal 1, emits.length
93
+ p emits[0]
94
+ assert_equal 'rewrited.bar', emits[0][0] # tag
95
+ assert_equal 'foo', emits[0][2]['message']
96
+ end
97
+
98
+ def test_emit_tag_parts_negative2
99
+ d1 = create_driver(%[
100
+ tag rewrited.${tag_parts[-2]}
101
+ ], 'input.access.foo.bar')
102
+ d1.run do
103
+ d1.emit({'message' => 'foo'})
104
+ end
105
+ emits = d1.emits
106
+ assert_equal 1, emits.length
107
+ p emits[0]
108
+ assert_equal 'rewrited.foo', emits[0][0] # tag
109
+ assert_equal 'foo', emits[0][2]['message']
110
+ end
111
+
112
+ def test_emit_hostname
113
+ d1 = create_driver(%[
114
+ tag rewrited.${hostname}
115
+ ], 'input.access')
116
+ d1.run do
117
+ d1.emit({'message' => 'foo'})
118
+ end
119
+ emits = d1.emits
120
+ assert_equal 1, emits.length
121
+ p emits[0]
122
+ hostname = `hostname`.chomp
123
+ assert_equal "rewrited.#{hostname}", emits[0][0] # tag
124
+ assert_equal 'foo', emits[0][2]['message']
125
+ end
126
+
127
+ def test_emit_hostname_short
128
+ d1 = create_driver(%[
129
+ tag rewrited.${hostname}
130
+ hostname_command hostname -s
131
+ ], 'input.access')
132
+ d1.run do
133
+ d1.emit({'message' => 'foo'})
134
+ end
135
+ emits = d1.emits
136
+ assert_equal 1, emits.length
137
+ p emits[0]
138
+ hostname_command = d1.instance.config['hostname_command']
139
+ hostname = `#{hostname_command}`.chomp
140
+ assert_equal "rewrited.#{hostname}", emits[0][0] # tag
141
+ assert_equal 'foo', emits[0][2]['message']
142
+ end
54
143
  end
data/test/plugin.rb CHANGED
@@ -2,17 +2,19 @@ class Fluent::RewriteTagNameMixinOutput < Fluent::Output
2
2
  Fluent::Plugin.register_output('rewrite_tag_name_mixin', self)
3
3
 
4
4
  config_param :tag, :string, :default => nil
5
+ config_param :hostname_command, :string, :default => 'hostname'
5
6
 
6
7
  include Fluent::HandleTagNameMixin
7
8
  include Fluent::Mixin::RewriteTagName
9
+ config_set_default :enable_placeholder_upcase, false
10
+ config_set_default :enable_placeholder_hostname, true
8
11
 
9
12
  def configure(conf)
10
13
  super
11
-
12
- if @tag.nil?
13
- raise Fluent::ConfigError, "'tag' parameter is required."
14
- end
15
14
 
15
+ if ( !@tag && !@remove_tag_prefix && !@remove_tag_suffix && !@add_tag_prefix && !@add_tag_suffix )
16
+ raise Fluent::ConfigError, "RewriteTagNameMixin: missing remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix."
17
+ end
16
18
  end
17
19
 
18
20
  def emit(tag, es, chain)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-mixin-rewrite-tag-name
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-20 00:00:00.000000000 Z
12
+ date: 2014-01-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -101,8 +101,9 @@ rubyforge_project:
101
101
  rubygems_version: 1.8.23
102
102
  signing_key:
103
103
  specification_version: 3
104
- summary: Fluentd mixin plugin to rewrite tag like rewrite-tag-filter for your any
105
- plugins.
104
+ summary: Fluentd mixin plugin to provides placeholder function for rewriting tag for
105
+ your any plugins as like fluent-plugin-rewrite-tag-filter. It will let you get easy
106
+ to implement tag placeholder for your own plugins.
106
107
  test_files:
107
108
  - test/helper.rb
108
109
  - test/mixin/test_rewrite_tag_name.rb