JSON Transform parser plugin for Fluentd
Overview
This is a parser plugin for fluentd. It is INCOMPATIBLE WITH FLUENTD v0.10.45 AND BELOW.
It was forker from fluent-plugin-json-transform plugin and has the following fixes:
- Fixing issue when you can't use the same filter plugin multiple times with different scripts.
Explanation: there was a sctrict rule that script class should be named as JSONTransformer. And when you defined a more than 1 script with different logic, anyway those classes should be named as JSONTransformer. As a result you have several scripts with different logic but with the same name.
Fix: define new parameter called class_name where you can define a custom class name and this is allow you to have a lot of scripts with different class names.
- Adding
paramssection with key-value pairs which can be passed to user script for usage.
Installation
gem install fluent-plugin-json-transform_ex --version 0.1.0
Configuration
<source>
type [tail|tcp|udp|syslog|http] # or a custom input type which accepts the "format" parameter
format json_transform
transform_script [nothing|flatten|custom]
script_path "/home/grayson/transform_script.rb" # ignored if transform_script != custom
class_name "CustomJSONTransformer" # [optional] default value is "JSONTransformer", ignored if transform_script != custom
<params> # any parameters which will be passed to "transform" method of class_name class
key1 value1
key2 value2
</params>
</source>
transform_script: nothing to do nothing, flatten to flatten JSON by concatenating nested keys (see below), or custom
script_path: ignored if not using custom script. Point this to a Ruby script which implements the class from class_name parameter.
class_name: [optional] ignored if not using custom script. Define name of a class which is used for transformation in script_path script.
Flatten script
Flattens nested JSON by concatenating nested keys with '.'. Example:
{
"hello": {
"world": true
},
"goodbye": {
"for": {
"now": true,
"ever": false
}
}
}
Becomes
{
"hello.world": true,
"goodbye.for.now": true,
"goodbye.for.ever": false
}
Filter Option
If you want to flatten your json after doing other parsing from the original source log.
<filter pattern>
@type json_transform
transform_script [nothing|flatten|custom]
script_path "/home/grayson/transform_script.rb" # ignored if transform_script != custom
class_name "CustomJSONTransformer" # [optional] default value is "JSONTransformer", ignored if transform_script != custom
<params> # any parameters which will be passed to "transform" method of class_name class
key1 value1
key2 value2
</params>
</filter>
Implementing transformer class
The transformer class should have an instance method transform which takes a Ruby hash and returns a Ruby hash. Pay attention that the name of a class should be the same as you defined in class_name parameter or JSONTransformer in case class_name parameter is not defined:
# lib/transform/flatten.rb
class JSONTransformer # or any class name defined in class_name parameter
def transform(json, params = {}) # params - [optional] passed parameters from config
return flatten(json, "")
end
def flatten(json, prefix)
json.keys.each do |key|
if prefix.empty?
full_path = key
else
full_path = [prefix, key].join('.')
end
if json[key].is_a?(Hash)
value = json[key]
json.delete key
json.merge! flatten(value, full_path)
else
value = json[key]
json.delete key
json[full_path] = value
end
end
return json
end
end