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 +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
|