Plugin Development
Installing custom plugins
To install a plugin, please put the ruby script in the /etc/fluent/plugin
directory.
Alternatively, you can create a Ruby Gem package that includes a lib/fluent/plugin/<TYPE>_<NAME>.rb
file. The TYPE is:
in
for input pluginsout
for output pluginsfilter
for filter pluginsbuf
for buffer pluginsparser
for parser pluginsformatter
for formatter plugins
For example, an email Output plugin would have the path: lib/fluent/plugin/out_mail.rb
. The packaged gem can be distributed and installed using RubyGems. For further information, please see the list of Fluentd plugins for third-party plugins.
Overview
The following slides can help the user understand how Fluentd works before they dive into writing their own plugins.
(The slides are taken from Naotoshi Seo's RubyKaigi 2014 talk.)
Fluentd version and Plugin API
Fluentd now has two active versions, v0.12 and v1.0. v0.12 is old stable and many people still use this version. v1.0 is current stable version and this version has brand-new Plugin API.
The important point is plugin for v0.12 works with v0.12 and v1.0, but new v1.0 API based Plugin doesn't work with v0.12.
This document based on v0.12 Plugin API.
Send a patch or fork?
If you have a problem with existing plugins or new feature idea, sending a patch is better. If the plugin author is non-active, try to become new plugin maintainer first. Forking a plugin and release alternative plugin, e.g. fluent-plugin-xxx-alt, is final approach.
Plugin versioning policy
If you don't have a your policy, following semantic versioning is better.
Semantic Versioning 2.0.0 - Semantic Versioning
The important thing is if your plugin breaks the backward compatibiliy, update major version to avoid user troubles. For example, new v0.14 API based plugin doesn't work with fluentd v0.12. So if you release your existing plugin with new v0.14 API, please update major version, 0.5.0
-> 1.0.0
, 1.2.0
-> 2.0.0
.
Writing Input Plugins
Extend the Fluent::Input class and implement the following methods. In initialize
, configure
and start
, super
should be called to call Input plugin default behaviour.
To submit events, use the router.emit(tag, time, record)
method, where tag
is the String, time
is the UNIX time integer and record
is a Hash object.
To submit multiple events in one call, use the router.emit_stream(tag, es)
and MultiEventStream
combo instead.
Record format
Fluentd plugins assume the record is a JSON so the key should be the String, not Symbol. If you emit a symbol keyed record, it may cause a problem.
Writing Buffered Output Plugins
Extend the Fluent::BufferedOutput class and implement the following methods. In initialize
, configure
and start
, super
should be called to call BufferedOutput plugin default behaviour.
Writing Time Sliced Output Plugins
Time Sliced Output plugins are extended versions of buffered output plugins. One example of a time sliced output is the out_file
plugin.
Note that Time Sliced Output plugins use file buffer by default. Thus the buffer_path
option is required.
To implement a Time Sliced Output plugin, extend the Fluent::TimeSlicedOutput class and implement the following methods.
Writing Non-buffered Output Plugins
Extend the Fluent::Output class and implement the following methods. Output plugin is often used for implementing filter like plugin. In initialize
, configure
and start
, super
should be called to call non-buffered Output plugin default behaviour.
Filter Plugins
This section shows how to write custom filters in addition to the core filter plugins. The plugin files whose names start with "filter_" are registered as filter plugins.
Here is the implementation of the most basic filter that passes through all events as-is:
In initialize
, configure
, start
and shutdown
, super
should be called to call Filter plugin default behaviour.
See Writing Input plugins section for the details of tag
, time
and record
.
filter_stream method
Almost plugins could be implemented by overriding filter
method. But if you want to mutate the event stream itself, you can override filter_stream
method.
Here is the default implementation of filter_stream
.
filter_stream
should return EventStream object.
Parser Plugins
Fluentd supports pluggable, customizable formats for input plugins. The plugin files whose names start with "parser_" are registered as Parser Plugins.
Here is an example of a custom parser that parses the following newline-delimited log format:
e.g., something like this
While it is not hard to write a regular expression to match this format, it is tricky to extract and save key names.
Here is the code to parse this custom format (let's call it time_key_value
). It takes one optional parameter called delimiter
, which is the delimiter for key-value pairs. It also takes time_format
to parse the time string. In initialize
, configure
and start
, super
should be called to call Parser plugin default behaviour.
Then, save this code in parser_time_key_value.rb
in a loadable plugin path. Then, if in_tail is configured as
Then, the log line like 2014-01-01T00:00:00 k=v a=b
is parsed as 2013-01-01 00:00:00 +0000 test: {"k":"v","a":"b"}
.
Parser API
Current Parser#parse
API is called with block. We will remove Parser#parse
with return value API since v0.14 or later.
Text Formatter Plugins
Fluentd supports pluggable, customizable formats for output plugins. The plugin files whose names start with "formatter_" are registered as Formatter Plugins.
Here is an example of a custom formatter that outputs events as CSVs. It takes a required parameter called "csv_fields" and outputs the fields. It assumes that the values of the fields are already valid CSV fields. In initialize
, configure
and start
, super
should be called to call Formatter plugin default behaviour.
Then, save this code in formatter_my_csv.rb
in a loadable plugin path. Then, if out_file is configured as
and if the record {"k1": 100, "k2": 200}
is matched, the output file should look like 100,200
Error stream
router
has emit_error_event
API to rescue invalid events. Emitted events via emit_error_event
are routed to @ERROR
label.
There are several use cases:
Rescue invalid event which hard to apply filter routine, e.g. don't
have geoip target field.
Rescue invalid event which hard to serialize in the output, e.g.
can't convert a record into BSON.
API
tag: String: recommend to use incoming event tag
time: Integer: recommend to use incoming event time
record: Hash: recommend to use incoming event record
error: Exception: use a raised exception
config_param
config_param
helper defines plugin parameter. You don't need to parse parameters manually. config_param
syntax is config_param :name, :type, options
. Here is simple example:
In this example, param1
is required string parameter. If a user doesn't specify param1
, fluentd raises an ConfigError
. On the other hand, param2
is optional integer parameter. If a user doesn't specify param2
, fluentd set 10
to param2
automatically. If a user sets "5" to param2
parameter, fluentd converts it into integer type automatically.
Access parameter value
config_param
sets parsed result to :name
instance variable after configure
call. See example below:
Supported types
Fluentd supports following built-in types for plugin parameter:
Supported options
default
: Specified parameter becomes optional.type
value ornil
are available:default: 10
,default: nil
.secret
: Specified parameter is masked when dump a configuration,e.g. start logs, in_monitor_agent result:
secret: true
deprecated
: Specified parameter is showed in warning log. Needdeprecated message for value:
deprecated: "Use xxx instead"
obsoleted
: Specified parameter is showed in error log withconfiguration error. Need obsoleted message for value:
obsoleted: "Use xxx instead"
These options can be combined.
Debugging plugins
Run fluentd
with the -vv
option to show debug messages:
The stdout and copy output plugins are useful for debugging. The stdout output plugin dumps matched events to the console. It can be used as follows:
The copy output plugin copies matched events to multiple output plugins. You can use it in conjunction with the stdout plugin:
You can use stdout filter instead of copy and stdout combination. The result is same as above but more simpler.
Writing test cases
Fluentd provides unit test frameworks for plugins:
Please see Fluentd's source code for details.
Run test
Fluentd test follows standard gem way and uses test-unit library. Use rake command.
If you want to run only one file, use TEST
environment variable:
Further Reading
If this article is incorrect or outdated, or omits critical information, please let us know. Fluentd is a open source project under Cloud Native Computing Foundation (CNCF). All components are available under the Apache 2 License.
Last updated