fluent-mixin-rewrite-tag-name 0.0.1 → 0.0.2
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.
- data/README.md +180 -2
- data/fluent-mixin-rewrite-tag-name.gemspec +2 -2
- data/lib/fluent/mixin/rewrite_tag_name.rb +83 -9
- data/test/mixin/test_rewrite_tag_name.rb +89 -0
- data/test/plugin.rb +6 -4
- metadata +5 -4
data/README.md
CHANGED
@@ -2,14 +2,192 @@
|
|
2
2
|
|
3
3
|
## Overview
|
4
4
|
|
5
|
-
Fluentd mixin plugin to
|
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
|
-
|
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.
|
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
|
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
|
-
|
16
|
-
|
17
|
-
|
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.
|
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-
|
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
|
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
|