Fluentd supports pluggable, customizable formats for output plugins. The plugin filenames starting with formatter_ are registered as Formatter Plugins.
Following is an example of a custom formatter (formatter_my_csv.rb) that outputs events in CSV format. It takes a required parameter called csv_fields and outputs the fields. It assumes that the values of the fields are valid CSV fields.
require'fluent/plugin/formatter'moduleFluent::PluginclassMyCSVFormatter<Formatter# Register MyCSVFormatter as 'my_csv'.Fluent::Plugin.register_formatter('my_csv', self) config_param :csv_fields,:array,value_type::string# This method does further processing. Configuration parameters can be# accessed either via `conf` hash or member variables.defconfigure(conf)superend# This is the method that formats the data output.defformat(tag,time,record) values = []# Look up each required field and collect them from the record @csv_fields.eachdo|field| v = record[field]unless v log.error"#{field} is missing."end values << v.to_send# Output by joining the fields with a comma values.join(',')endendend
Save this as formatter_my_csv.rb in a loadable plugin path.
With out_file output plugin:
For a matched record e.g. {"k1": 100, "k2": 200}, the output CSV file would look like this:
How To Use Formatters From Plugins
Formatter plugins are designed to be used from other plugins, like Input, Filter and Output. Formatter plugin helper helps achieve this:
The formatter plugins implement filter method to format the input Hash record as a String object.
#format(tag, time, record)
It receives an event represented by tag, time and record; and, after formatting returns a String object.
Formatter plugins must implement this method.
Writing Tests
Fluentd formatter plugin has one or more points to be tested. Others (parsing configurations, controlling buffers, retries, flushes and many others) are controlled by the Fluentd core.
Fluentd also provides test driver for plugins. You can write tests for your own plugins very easily:
Overview of Tests
Testing for formatter plugins is mainly for:
Validation of configuration parameters (i.e. #configure)
Validation of the formatted records
To make testing easy, the plugin test driver provides a logger and the functionality to override the system, parser and other configurations.
The lifecycle of the plugin and its test driver is:
Instantiate plugin driver which then instantiates the plugin
Configure plugin
Run test code
Assert results of tests by data provided by the driver
# in class definition
helpers :formatter
# in #configure
@formatter = formatter_create(type: 'json')
# in #filter, #format or ...
es.each do |time, record|
row = @formatter.format(@tag, time, record)
# ...
end
# test/plugin/test_formatter_your_own.rb
require 'test/unit'
require 'fluent/test/driver/formatter'
# your own plugin
require 'fluent/plugin/formatter_your_own'
class FormatterYourOwnTest < Test::Unit::TestCase
def setup
# common setup
end
CONFIG = %[
fields a,b,c
]
def create_driver(conf = CONF)
Fluent::Test::Driver::Formatter.new(Fluent::Plugin::YourOwnFormatter).configure(conf)
end
sub_test_case 'configured with invalid configurations' do
test 'empty' do
assert_raise(Fluent::ConfigError) do
create_driver('')
end
end
# ...
end
sub_test_case 'plugin will format record' do
test 'record has a field' do
d = create_driver(CONFIG)
tag = 'test'
time = event_time
record = { 'message' => 'This is message' }
formatted = d.instance.format(tag, time, record)
expected = '...'
assert_equal(expected, formatted)
end
end
end