fluent-plugin-record-reformer 0.2.1 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +23 -6
- data/fluent-plugin-record-reformer.gemspec +1 -1
- data/lib/fluent/plugin/out_record_reformer.rb +54 -19
- data/spec/out_record_reformer_spec.rb +64 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f79ddbaecca21d91a17132b991c9f031b5a19b01
|
4
|
+
data.tar.gz: e6f3777a3a2fdc0fe14887c3d745dfd38e39c60a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5193f5ee853ff6af02e119759bc8ec6a6c018f1a69bad34511757f62bd95918c2c3dc766eb3bc485ad47e65829a88e44da16e63a5238150314b9dca4f137e678
|
7
|
+
data.tar.gz: dc3313b3754851512e110247fd0c184c9130e9c2137f5c6adc39c62c173e9c6f2a3379b55b29dd2bf453c88e036722817a19455e72389e05e25f00e02da77585
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -67,7 +67,7 @@ Example:
|
|
67
67
|
|
68
68
|
This results in same, but please note that following option parameters are reserved, so can not be used as a record key.
|
69
69
|
|
70
|
-
## Parameters
|
70
|
+
## Option Parameters
|
71
71
|
|
72
72
|
- output_tag
|
73
73
|
|
@@ -98,11 +98,28 @@ The keys of input json are available as placeholders. In the above example,
|
|
98
98
|
|
99
99
|
shall be available. In addition, following placeholders are reserved:
|
100
100
|
|
101
|
-
* ${hostname}
|
102
|
-
* ${tag}
|
103
|
-
* ${time}
|
104
|
-
* ${tags[N]}
|
105
|
-
* ${tag\_parts[N]}
|
101
|
+
* ${hostname} Hostname of the running machine
|
102
|
+
* ${tag} Input tag
|
103
|
+
* ${time} Time of the event
|
104
|
+
* ${tags[N]} (Obsolete. Use tag\_parts) Input tag splitted by '.'
|
105
|
+
* ${tag\_parts[N]} Input tag splitted by '.' indexed with N such as `${tag_parts[0]}`, `${tag_parts[-1]}`.
|
106
|
+
* ${tag\_prefix[N]} Tag parts before and on the index N. For example,
|
107
|
+
|
108
|
+
Input tag: prefix.test.tag.suffix
|
109
|
+
|
110
|
+
${tag_prefix[0]} => prefix
|
111
|
+
${tag_prefix[1]} => prefix.test
|
112
|
+
${tag_prefix[-2]} => prefix.test.tag
|
113
|
+
${tag_prefix[-1]} => prefix.test.tag.suffix
|
114
|
+
|
115
|
+
* ${tag\_suffix[N]} Tag parts after and on the index N. For example,
|
116
|
+
|
117
|
+
Input tag: prefix.test.tag.suffix
|
118
|
+
|
119
|
+
${tag_suffix[0]} => prefix.test.tag.suffix
|
120
|
+
${tag_suffix[1]} => test.tag.suffix
|
121
|
+
${tag_suffix[-2]} => tag.suffix
|
122
|
+
${tag_suffix[-1]} => suffix
|
106
123
|
|
107
124
|
It is also possible to write a ruby code in placeholders if you set `enable_ruby true` option, so you may write some codes as
|
108
125
|
|
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.name = "fluent-plugin-record-reformer"
|
6
|
-
gem.version = "0.2.
|
6
|
+
gem.version = "0.2.2"
|
7
7
|
gem.authors = ["Naotoshi Seo"]
|
8
8
|
gem.email = "sonots@gmail.com"
|
9
9
|
gem.homepage = "https://github.com/sonots/fluent-plugin-record-reformer"
|
@@ -6,10 +6,6 @@ module Fluent
|
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
super
|
9
|
-
# require utilities for placeholder
|
10
|
-
require 'pathname'
|
11
|
-
require 'uri'
|
12
|
-
require 'cgi'
|
13
9
|
end
|
14
10
|
|
15
11
|
config_param :output_tag, :string
|
@@ -42,6 +38,10 @@ module Fluent
|
|
42
38
|
|
43
39
|
@placeholder_expander =
|
44
40
|
if @enable_ruby
|
41
|
+
# require utilities which would be used in ruby placeholders
|
42
|
+
require 'pathname'
|
43
|
+
require 'uri'
|
44
|
+
require 'cgi'
|
45
45
|
RubyPlaceholderExpander.new
|
46
46
|
else
|
47
47
|
PlaceholderExpander.new
|
@@ -59,19 +59,21 @@ module Fluent
|
|
59
59
|
|
60
60
|
def emit(tag, es, chain)
|
61
61
|
tag_parts = tag.split('.')
|
62
|
+
tag_prefix = tag_prefix(tag_parts)
|
63
|
+
tag_suffix = tag_suffix(tag_parts)
|
62
64
|
es.each { |time, record|
|
63
|
-
new_tag, new_record = reform(@output_tag, record, tag, tag_parts, @time_proc.call(time))
|
65
|
+
new_tag, new_record = reform(@output_tag, record, tag, tag_parts, tag_prefix, tag_suffix, @time_proc.call(time))
|
64
66
|
Engine.emit(new_tag, time, new_record)
|
65
67
|
}
|
66
68
|
chain.next
|
67
69
|
rescue => e
|
68
|
-
$log.warn "record_reformer: #{e.class} #{e.message} #{e.backtrace.
|
70
|
+
$log.warn "record_reformer: #{e.class} #{e.message} #{e.backtrace.first}"
|
69
71
|
end
|
70
72
|
|
71
73
|
private
|
72
74
|
|
73
|
-
def reform(output_tag, record, tag, tag_parts, time)
|
74
|
-
@placeholder_expander.prepare_placeholders(record, tag, tag_parts, @hostname, time)
|
75
|
+
def reform(output_tag, record, tag, tag_parts, tag_prefix, tag_suffix, time)
|
76
|
+
@placeholder_expander.prepare_placeholders(record, tag, tag_parts, tag_prefix, tag_suffix, @hostname, time)
|
75
77
|
new_tag = @placeholder_expander.expand(output_tag)
|
76
78
|
|
77
79
|
new_record = @renew_record ? {} : record.dup
|
@@ -81,11 +83,30 @@ module Fluent
|
|
81
83
|
[new_tag, new_record]
|
82
84
|
end
|
83
85
|
|
86
|
+
def tag_prefix(tag_parts)
|
87
|
+
return [] if tag_parts.empty?
|
88
|
+
tag_prefix = [tag_parts.first]
|
89
|
+
1.upto(tag_parts.size-1).each do |i|
|
90
|
+
tag_prefix[i] = "#{tag_prefix[i-1]}.#{tag_parts[i]}"
|
91
|
+
end
|
92
|
+
tag_prefix
|
93
|
+
end
|
94
|
+
|
95
|
+
def tag_suffix(tag_parts)
|
96
|
+
return [] if tag_parts.empty?
|
97
|
+
rev_tag_parts = tag_parts.reverse
|
98
|
+
rev_tag_suffix = [rev_tag_parts.first]
|
99
|
+
1.upto(tag_parts.size-1).each do |i|
|
100
|
+
rev_tag_suffix[i] = "#{rev_tag_parts[i]}.#{rev_tag_suffix[i-1]}"
|
101
|
+
end
|
102
|
+
rev_tag_suffix.reverse
|
103
|
+
end
|
104
|
+
|
84
105
|
class PlaceholderExpander
|
85
106
|
# referenced https://github.com/fluent/fluent-plugin-rewrite-tag-filter, thanks!
|
86
107
|
attr_reader :placeholders
|
87
108
|
|
88
|
-
def prepare_placeholders(record, tag, tag_parts, hostname, time)
|
109
|
+
def prepare_placeholders(record, tag, tag_parts, tag_prefix, tag_suffix, hostname, time)
|
89
110
|
placeholders = {
|
90
111
|
'${time}' => time,
|
91
112
|
'${tag}' => tag,
|
@@ -93,17 +114,27 @@ module Fluent
|
|
93
114
|
}
|
94
115
|
|
95
116
|
size = tag_parts.size
|
96
|
-
|
117
|
+
|
118
|
+
tag_parts.each_with_index { |t, idx|
|
97
119
|
placeholders.store("${tag_parts[#{idx}]}", t)
|
98
120
|
placeholders.store("${tag_parts[#{idx-size}]}", t) # support tag_parts[-1]
|
99
|
-
|
100
|
-
|
101
|
-
tag_parts.each_with_index do |t, idx|
|
121
|
+
|
122
|
+
# tags is just for old version compatibility
|
102
123
|
placeholders.store("${tags[#{idx}]}", t)
|
103
124
|
placeholders.store("${tags[#{idx-size}]}", t) # support tags[-1]
|
104
|
-
|
125
|
+
}
|
126
|
+
|
127
|
+
tag_prefix.each_with_index { |t, idx|
|
128
|
+
placeholders.store("${tag_prefix[#{idx}]}", t)
|
129
|
+
placeholders.store("${tag_prefix[#{idx-size}]}", t) # support tag_prefix[-1]
|
130
|
+
}
|
105
131
|
|
106
|
-
|
132
|
+
tag_suffix.each_with_index { |t, idx|
|
133
|
+
placeholders.store("${tag_suffix[#{idx}]}", t)
|
134
|
+
placeholders.store("${tag_suffix[#{idx-size}]}", t) # support tag_suffix[-1]
|
135
|
+
}
|
136
|
+
|
137
|
+
record.each { |k, v|
|
107
138
|
placeholders.store("${#{k}}", v)
|
108
139
|
}
|
109
140
|
|
@@ -111,10 +142,10 @@ module Fluent
|
|
111
142
|
end
|
112
143
|
|
113
144
|
def expand(str)
|
114
|
-
str.gsub(/(\${[a-z_]+(\[-?[0-9]+\])?}|__[A-Z_]+__)/)
|
115
|
-
$log.warn "record_reformer: unknown placeholder `#{$1}` found
|
145
|
+
str.gsub(/(\${[a-z_]+(\[-?[0-9]+\])?}|__[A-Z_]+__)/) {
|
146
|
+
$log.warn "record_reformer: unknown placeholder `#{$1}` found" unless @placeholders.include?($1)
|
116
147
|
@placeholders[$1]
|
117
|
-
|
148
|
+
}
|
118
149
|
end
|
119
150
|
end
|
120
151
|
|
@@ -126,12 +157,16 @@ module Fluent
|
|
126
157
|
# @param [Hash] record the record, one of information
|
127
158
|
# @param [String] tag the tag
|
128
159
|
# @param [Array] tag_parts the tag parts (tag splitted by .)
|
160
|
+
# @param [Array] tag_prefix the tag prefix parts
|
161
|
+
# @param [Array] tag_suffix the tag suffix parts
|
129
162
|
# @param [String] hostname the hostname
|
130
163
|
# @param [Time] time the time
|
131
|
-
def prepare_placeholders(record, tag, tag_parts, hostname, time)
|
164
|
+
def prepare_placeholders(record, tag, tag_parts, tag_prefix, tag_suffix, hostname, time)
|
132
165
|
struct = UndefOpenStruct.new(record)
|
133
166
|
struct.tag = tag
|
134
167
|
struct.tags = struct.tag_parts = tag_parts # tags is for old version compatibility
|
168
|
+
struct.tag_prefix = tag_prefix
|
169
|
+
struct.tag_suffix = tag_suffix
|
135
170
|
struct.time = time
|
136
171
|
struct.hostname = hostname
|
137
172
|
@placeholders = struct
|
@@ -10,7 +10,7 @@ describe Fluent::RecordReformerOutput do
|
|
10
10
|
hostname ${hostname}
|
11
11
|
tag ${tag}
|
12
12
|
time ${time.strftime('%S')}
|
13
|
-
message ${hostname} ${tag_parts.last} ${message}
|
13
|
+
message ${hostname} ${tag_parts.last} ${URI.escape(message)}
|
14
14
|
]
|
15
15
|
let(:tag) { 'test.tag' }
|
16
16
|
let(:tag_parts) { tag.split('.') }
|
@@ -31,8 +31,8 @@ describe Fluent::RecordReformerOutput do
|
|
31
31
|
let(:time) { Time.now }
|
32
32
|
let(:emit) do
|
33
33
|
driver.run do
|
34
|
-
driver.emit({'foo'=>'bar', 'message' => 1}, time.to_i)
|
35
|
-
driver.emit({'foo'=>'bar', 'message' => 2}, time.to_i)
|
34
|
+
driver.emit({'foo'=>'bar', 'message' => '1'}, time.to_i)
|
35
|
+
driver.emit({'foo'=>'bar', 'message' => '2'}, time.to_i)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -176,5 +176,66 @@ describe Fluent::RecordReformerOutput do
|
|
176
176
|
end
|
177
177
|
it { emit }
|
178
178
|
end
|
179
|
+
|
180
|
+
context '${tag_prefix[N]} and ${tag_suffix[N]}' do
|
181
|
+
let(:config) {%[
|
182
|
+
type reformed
|
183
|
+
output_tag ${tag_suffix[-2]}
|
184
|
+
enable_ruby no
|
185
|
+
|
186
|
+
hostname ${hostname}
|
187
|
+
tag ${tag}
|
188
|
+
time ${time}
|
189
|
+
message ${tag_prefix[1]} ${tag_prefix[-2]} ${tag_suffix[2]} ${tag_suffix[-3]} ${message}
|
190
|
+
]}
|
191
|
+
let(:tag) { 'prefix.test.tag.suffix' }
|
192
|
+
let(:tag_parts) { tag.split('.') }
|
193
|
+
before do
|
194
|
+
Fluent::Engine.stub(:now).and_return(time)
|
195
|
+
Fluent::Engine.should_receive(:emit).with("tag.suffix", time.to_i, {
|
196
|
+
'foo' => 'bar',
|
197
|
+
'message' => "prefix.test prefix.test.tag tag.suffix test.tag.suffix 1",
|
198
|
+
'hostname' => hostname,
|
199
|
+
'tag' => tag,
|
200
|
+
'time' => time.to_i.to_s, # hmm, want to remove ${time} placeholder
|
201
|
+
})
|
202
|
+
Fluent::Engine.should_receive(:emit).with("tag.suffix", time.to_i, {
|
203
|
+
'foo' => 'bar',
|
204
|
+
'message' => "prefix.test prefix.test.tag tag.suffix test.tag.suffix 2",
|
205
|
+
'hostname' => hostname,
|
206
|
+
'tag' => tag,
|
207
|
+
'time' => time.to_i.to_s, # hmm, want to remove ${time} placeholder
|
208
|
+
})
|
209
|
+
end
|
210
|
+
it { emit }
|
211
|
+
end
|
212
|
+
|
213
|
+
context '${tag_prefix[N]} and ${tag_suffix[N]} with ruby enabled' do
|
214
|
+
let(:config) { CONFIG + %[
|
215
|
+
test_tag ${tag_prefix[1]} ${tag_prefix[-2]} ${tag_suffix[2]} ${tag_suffix[-3]}
|
216
|
+
]}
|
217
|
+
let(:tag) { 'prefix.test.tag.suffix' }
|
218
|
+
let(:tag_parts) { tag.split('.') }
|
219
|
+
before do
|
220
|
+
Fluent::Engine.stub(:now).and_return(time)
|
221
|
+
Fluent::Engine.should_receive(:emit).with("reformed.#{tag}", time.to_i, {
|
222
|
+
'foo' => 'bar',
|
223
|
+
'message' => "#{hostname} #{tag_parts.last} 1",
|
224
|
+
'hostname' => hostname,
|
225
|
+
'tag' => tag,
|
226
|
+
'time' => time.strftime('%S'),
|
227
|
+
'test_tag' => "prefix.test prefix.test.tag tag.suffix test.tag.suffix",
|
228
|
+
})
|
229
|
+
Fluent::Engine.should_receive(:emit).with("reformed.#{tag}", time.to_i, {
|
230
|
+
'foo' => 'bar',
|
231
|
+
'message' => "#{hostname} #{tag_parts.last} 2",
|
232
|
+
'hostname' => hostname,
|
233
|
+
'tag' => tag,
|
234
|
+
'time' => time.strftime('%S'),
|
235
|
+
'test_tag' => "prefix.test prefix.test.tag tag.suffix test.tag.suffix",
|
236
|
+
})
|
237
|
+
end
|
238
|
+
it { emit }
|
239
|
+
end
|
179
240
|
end
|
180
241
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-record-reformer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naotoshi Seo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|