Skip to content

Commit 4512c5b

Browse files
authored
Merge pull request #33 from smallcreep/Replace
Implement replace
2 parents 93f2e7a + 6fb6c22 commit 4512c5b

File tree

3 files changed

+101
-6
lines changed

3 files changed

+101
-6
lines changed

README.md

+42-6
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,48 @@ then you got new record like below:
148148
{"key1":"hoge", "key2":"foo"}
149149
```
150150

151+
### replace_keys_value
152+
153+
If you want to replace specific value for keys you can use `replace` section.
154+
155+
```conf
156+
<filter pattern>
157+
@type record_modifier
158+
159+
# replace key key1
160+
<replace>
161+
# your key name
162+
key key1
163+
# your regexp
164+
expression /^(?<start>.+).{2}(?<end>.+)$/
165+
# replace string
166+
replace \\k<start>ors\\k<end>
167+
</replace>
168+
# replace key key2
169+
<replace>
170+
# your key name
171+
key key2
172+
# your regexp
173+
expression /^(.{1}).{2}(.{1})$/
174+
# replace string
175+
replace \\1ors\\2
176+
</replace>
177+
</filter>
178+
```
179+
180+
If following record is passed:
181+
182+
```js
183+
{"key1":"hoge", "key2":"hoge", "key3":"bar"}
184+
```
185+
186+
then you got new record like below:
187+
188+
```js
189+
{"key1":"horse", "key2":"horse", "key3":"bar"}
190+
```
191+
192+
151193
### Ruby code trick for complex logic
152194

153195
If you need own complex logic in filter, writing filter plugin is better. But if you don't want to write new plugin, you can use temporal key trick like below:
@@ -174,12 +216,6 @@ In v0.10, you can use `record_modifier` output to emulate filter. `record_modifi
174216
foo bar
175217
</match>
176218

177-
## TODO
178-
179-
* Adding following features if needed
180-
181-
* Replace record value
182-
183219
## Copyright
184220

185221
<table>

lib/fluent/plugin/filter_record_modifier.rb

+22
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ class Plugin::RecordModifierFilter < Plugin::Filter
3131
This option is exclusive with `remove_keys`.
3232
DESC
3333

34+
config_section :replace, param_name: :replaces, multi: true do
35+
desc"The field name to which the regular expression is applied"
36+
config_param :key, :string
37+
desc "The regular expression"
38+
config_param :expression do |value|
39+
if value.start_with?("/") && value.end_with?("/")
40+
Regexp.compile(value[1..-2])
41+
else
42+
$log.warn("You should use \"pattern /#{value}/\" instead of \"pattern #{value}\"")
43+
Regexp.compile(value)
44+
end
45+
end
46+
desc "The replacement string"
47+
config_param :replace, :string
48+
end
49+
3450
def configure(conf)
3551
super
3652

@@ -97,6 +113,12 @@ def filter(tag, time, record)
97113
record = modified
98114
end
99115

116+
if @replaces.any?
117+
@replaces.each {|replace|
118+
record[replace.key] = record[replace.key].gsub(replace.expression, replace.replace) if record.include?(replace.key) && replace.expression.match(record[replace.key])
119+
}
120+
end
121+
100122
record = change_encoding(record) if @char_encoding
101123
record
102124
end

test/test_filter_record_modifier.rb

+37
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,43 @@ def test_prepare_values
141141
assert_equal [{"k1" => 'v', "test_key" => 'foo'}], d.filtered.map(&:last)
142142
end
143143

144+
def test_replace_values
145+
d = create_driver %[
146+
<replace>
147+
key k1
148+
expression /^(?<start>.+).{2}(?<end>.+)$/
149+
replace \\k<start>ors\\k<end>
150+
</replace>
151+
<replace>
152+
key k2
153+
expression /^(.{1}).{2}(.{1})$/
154+
replace \\1ors\\2
155+
</replace>
156+
]
157+
158+
d.run(default_tag: @tag) do
159+
d.feed("k1" => 'hoge', "k2" => 'hoge', "k3" => 'bar')
160+
end
161+
162+
assert_equal [{"k1" => 'horse', "k2" => 'horse', "k3" => 'bar'}], d.filtered.map(&:last)
163+
end
164+
165+
def test_does_not_replace
166+
d = create_driver %[
167+
<replace>
168+
key k1
169+
expression /^(?<start>.+).{2}(?<end>.+)$/
170+
replace \\k<start>ors\\k<end>
171+
</replace>
172+
]
173+
174+
d.run(default_tag: @tag) do
175+
d.feed("k1" => 'hog')
176+
end
177+
178+
assert_equal [{"k1" => 'hog'}], d.filtered.map(&:last)
179+
end
180+
144181
sub_test_case 'frozen check' do
145182
def test_set_char_encoding
146183
d = create_driver %[

0 commit comments

Comments
 (0)