fluent-plugin-record-reformer 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 55ba6719a96af4f1c33c52d970579a9006ef9a7c
4
- data.tar.gz: 15cd6f42ed2f5b0b995f20560cf9974d12e23bda
3
+ metadata.gz: f79ddbaecca21d91a17132b991c9f031b5a19b01
4
+ data.tar.gz: e6f3777a3a2fdc0fe14887c3d745dfd38e39c60a
5
5
  SHA512:
6
- metadata.gz: 8758e09cd82e2f2fd50076811bf7a25961a2782f5ac6081185567ff8e874b1bb312aeaae546acfa17411a26f6c0af2c85ed47af99416cb7448ac4a65176e5815
7
- data.tar.gz: 4ae98eedf0aafea25057b67a9d2f2f189f54c1063d00ecd70f90075c317171089e614bc3f00115f027037ca5a23eee51c0c7b3c75f6f8b150174792f1c0cf972
6
+ metadata.gz: 5193f5ee853ff6af02e119759bc8ec6a6c018f1a69bad34511757f62bd95918c2c3dc766eb3bc485ad47e65829a88e44da16e63a5238150314b9dca4f137e678
7
+ data.tar.gz: dc3313b3754851512e110247fd0c184c9130e9c2137f5c6adc39c62c173e9c6f2a3379b55b29dd2bf453c88e036722817a19455e72389e05e25f00e02da77585
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.2.2 (2014/01/20)
2
+
3
+ Enhancement:
4
+
5
+ * Add `tag_prefix` and `tag_suffix` placeholders. Thanks to [xthexder](https://github.com/xthexder).
6
+
1
7
  ## 0.2.1 (2014/01/15)
2
8
 
3
9
  Enhancement:
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} hostname
102
- * ${tag} input tag
103
- * ${time} time of the event
104
- * ${tags[N]} input tag splitted by '.' (obsolete. use tag\_parts)
105
- * ${tag\_parts[N]} input tag splitted by '.' indexed with N such as `${tag_parts[0]}`, `${tag_parts[-1]}`.
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.1"
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.join(', ')}"
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
- tag_parts.each_with_index do |t, idx|
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
- end
100
- # tags is just for old version compatibility
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
- end
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
- record.each {|k, v|
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_]+__)/) do
115
- $log.warn "record_reformer: unknown placeholder `#{$1}` found in a tag `#{tag}`" unless @placeholders.include?($1)
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
- end
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.1
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-15 00:00:00.000000000 Z
11
+ date: 2014-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd