mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 06:37:19 -04:00
286 lines
8.6 KiB
Text
286 lines
8.6 KiB
Text
:register_method: true
|
|
:multi_receive_method: true
|
|
:plugintype: output
|
|
:pluginclass: Outputs
|
|
:pluginname: example
|
|
:pluginnamecap: Example
|
|
:plugintypecap: Output
|
|
:sversion: '0.0.1'
|
|
|
|
:pluginrepo: https://github.com/logstash-plugins/logstash-output-java_output_example[example output plugin]
|
|
|
|
:blockfilter: true
|
|
|
|
|
|
[[java-output-plugin]]
|
|
=== How to write a Java output plugin
|
|
|
|
// Pulls in shared section: Setting Up Environment
|
|
include::include/javapluginsetup.asciidoc[]
|
|
|
|
[float]
|
|
=== Code the plugin
|
|
|
|
The example output plugin prints events to the console using the event's
|
|
`toString` method. Let's look at the main class in the example output:
|
|
|
|
[source,java]
|
|
-----
|
|
@LogstashPlugin(name = "java_output_example")
|
|
public class JavaOutputExample implements Output {
|
|
|
|
public static final PluginConfigSpec<String> PREFIX_CONFIG =
|
|
PluginConfigSpec.stringSetting("prefix", "");
|
|
|
|
private final String id;
|
|
private String prefix;
|
|
private PrintStream printer;
|
|
private final CountDownLatch done = new CountDownLatch(1);
|
|
private volatile boolean stopped = false;
|
|
|
|
public JavaOutputExample(final String id, final Configuration configuration, final Context context) {
|
|
this(id, configuration, context, System.out);
|
|
}
|
|
|
|
JavaOutputExample(final String id, final Configuration config, final Context context, OutputStream targetStream) {
|
|
this.id = id;
|
|
prefix = config.get(PREFIX_CONFIG);
|
|
printer = new PrintStream(targetStream);
|
|
}
|
|
|
|
@Override
|
|
public void output(final Collection<Event> events) {
|
|
Iterator<Event> z = events.iterator();
|
|
while (z.hasNext() && !stopped) {
|
|
String s = prefix + z.next();
|
|
printer.println(s);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void stop() {
|
|
stopped = true;
|
|
done.countDown();
|
|
}
|
|
|
|
@Override
|
|
public void awaitStop() throws InterruptedException {
|
|
done.await();
|
|
}
|
|
|
|
@Override
|
|
public Collection<PluginConfigSpec<?>> configSchema() {
|
|
return Collections.singletonList(PREFIX_CONFIG);
|
|
}
|
|
|
|
@Override
|
|
public String getId() {
|
|
return id;
|
|
}
|
|
}
|
|
-----
|
|
|
|
Let's step through and examine each part of that class.
|
|
|
|
[float]
|
|
==== Class declaration
|
|
|
|
[source,java]
|
|
-----
|
|
@LogstashPlugin(name="java_output_example")
|
|
public class JavaOutputExample implements Output {
|
|
-----
|
|
|
|
Notes about the class declaration:
|
|
|
|
* All Java plugins must be annotated with the `@LogstashPlugin` annotation. Additionally:
|
|
** The `name` property of the annotation must be supplied and defines the name of the plugin as it will be used
|
|
in the Logstash pipeline definition. For example, this output would be referenced in the output section of the
|
|
Logstash pipeline definition as `output { java_output_example => { .... } }`
|
|
** The value of the `name` property must match the name of the class excluding casing and underscores.
|
|
* The class must implement the `co.elastic.logstash.api.Output` interface.
|
|
* Java plugins may not be created in the `org.logstash` or `co.elastic.logstash` packages to prevent potential
|
|
clashes with classes in Logstash itself.
|
|
|
|
[float]
|
|
==== Plugin settings
|
|
|
|
The snippet below contains both the setting definition and the method referencing it:
|
|
|
|
[source,java]
|
|
-----
|
|
public static final PluginConfigSpec<String> PREFIX_CONFIG =
|
|
PluginConfigSpec.stringSetting("prefix", "");
|
|
|
|
@Override
|
|
public Collection<PluginConfigSpec<?>> configSchema() {
|
|
return Collections.singletonList(PREFIX_CONFIG);
|
|
}
|
|
-----
|
|
|
|
The `PluginConfigSpec` class allows developers to specify the settings that a
|
|
plugin supports complete with setting name, data type, deprecation status,
|
|
required status, and default value. In this example, the `prefix` setting
|
|
defines an optional prefix to include in the output of the event. The setting is
|
|
not required and if it is not explicitly set, it defaults to the empty string.
|
|
|
|
The `configSchema` method must return a list of all settings that the plugin
|
|
supports. In a future phase of the Java plugin project, the Logstash execution
|
|
engine will validate that all required settings are present and that no
|
|
unsupported settings are present.
|
|
|
|
[float]
|
|
==== Constructor and initialization
|
|
|
|
[source,java]
|
|
-----
|
|
private final String id;
|
|
private String prefix;
|
|
private PrintStream printer;
|
|
|
|
public JavaOutputExample(final String id, final Configuration configuration, final Context context) {
|
|
this(configuration, context, System.out);
|
|
}
|
|
|
|
JavaOutputExample(final String id, final Configuration config, final Context context, OutputStream targetStream) {
|
|
this.id = id;
|
|
prefix = config.get(PREFIX_CONFIG);
|
|
printer = new PrintStream(targetStream);
|
|
}
|
|
-----
|
|
|
|
All Java output plugins must have a constructor taking a `String` id and a
|
|
`Configuration` and `Context` argument. This is the constructor that will be
|
|
used to instantiate them at runtime. The retrieval and validation of all plugin
|
|
settings should occur in this constructor. In this example, the values of the
|
|
`prefix` setting is retrieved and stored in a local variable for later use in
|
|
the `output` method. In this example, a second, pacakge private constructor is
|
|
defined that is useful for unit testing with a `Stream` other than `System.out`.
|
|
|
|
Any additional initialization may occur in the constructor as well. If there are
|
|
any unrecoverable errors encountered in the configuration or initialization of
|
|
the output plugin, a descriptive exception should be thrown. The exception will
|
|
be logged and will prevent Logstash from starting.
|
|
|
|
[float]
|
|
==== Output method
|
|
|
|
[source,java]
|
|
-----
|
|
@Override
|
|
public void output(final Collection<Event> events) {
|
|
Iterator<Event> z = events.iterator();
|
|
while (z.hasNext() && !stopped) {
|
|
String s = prefix + z.next();
|
|
printer.println(s);
|
|
}
|
|
}
|
|
-----
|
|
|
|
Outputs may send events to local sinks such as the console or a file or to remote systems such as Elasticsearch
|
|
or other external systems. In this example, the events are printed to the local console.
|
|
|
|
[float]
|
|
==== Stop and awaitStop methods
|
|
|
|
[source,java]
|
|
-----
|
|
private final CountDownLatch done = new CountDownLatch(1);
|
|
private volatile boolean stopped;
|
|
|
|
@Override
|
|
public void stop() {
|
|
stopped = true;
|
|
done.countDown();
|
|
}
|
|
|
|
@Override
|
|
public void awaitStop() throws InterruptedException {
|
|
done.await();
|
|
}
|
|
-----
|
|
|
|
The `stop` method notifies the output to stop sending events. The stop mechanism
|
|
may be implemented in any way that honors the API contract though a `volatile
|
|
boolean` flag works well for many use cases. Because this output example is so
|
|
simple, its `output` method does not check for the stop flag.
|
|
|
|
Outputs stop both asynchronously and cooperatively. Use the `awaitStop` method
|
|
to block until the output has completed the stop process. Note that this method
|
|
should **not** signal the output to stop as the `stop` method does. The
|
|
awaitStop mechanism may be implemented in any way that honors the API contract
|
|
though a `CountDownLatch` works well for many use cases.
|
|
|
|
[float]
|
|
==== getId method
|
|
|
|
[source,java]
|
|
-----
|
|
@Override
|
|
public String getId() {
|
|
return id;
|
|
}
|
|
-----
|
|
|
|
For output plugins, the `getId` method should always return the id that was provided to the plugin through its
|
|
constructor at instantiation time.
|
|
|
|
[float]
|
|
==== Unit tests
|
|
|
|
Lastly, but certainly not least importantly, unit tests are strongly encouraged.
|
|
The example output plugin includes an
|
|
https://github.com/logstash-plugins/logstash-output-java_output_example/blob/main/src/test/java/org/logstashplugins/JavaOutputExampleTest.java[example unit
|
|
test] that you can use as a template for your own.
|
|
|
|
|
|
// Pulls in shared section about Packaging and Deploying
|
|
include::include/javapluginpkg.asciidoc[]
|
|
|
|
[float]
|
|
=== Running Logstash with the Java output plugin
|
|
|
|
The following is a minimal Logstash configuration that can be used to test that
|
|
the Java output plugin is correctly installed and functioning.
|
|
|
|
[source,java]
|
|
-----
|
|
input {
|
|
generator { message => "Hello world!" count => 1 }
|
|
}
|
|
output {
|
|
java_output_example {}
|
|
}
|
|
-----
|
|
|
|
Copy the above Logstash configuration to a file such as `java_output.conf`.
|
|
Logstash should then be started with:
|
|
|
|
[source,txt]
|
|
-----
|
|
bin/logstash -f /path/to/java_output.conf
|
|
-----
|
|
|
|
|
|
The expected Logstash output (excluding initialization) with the configuration
|
|
above is:
|
|
|
|
[source,txt]
|
|
-----
|
|
{"@timestamp":"yyyy-MM-ddTHH:mm:ss.SSSZ","message":"Hello world!","@version":"1","host":"<yourHostname>","sequence":0}
|
|
-----
|
|
|
|
[float]
|
|
=== Feedback
|
|
|
|
If you have any feedback on Java plugin support in Logstash, please comment on our
|
|
https://github.com/elastic/logstash/issues/9215[main Github issue] or post in the
|
|
https://discuss.elastic.co/c/logstash[Logstash forum].
|
|
|
|
:pluginrepo!:
|
|
:sversion!:
|
|
:plugintypecap!:
|
|
:pluginnamecap!:
|
|
:pluginname!:
|
|
:pluginclass!:
|
|
:plugintype!:
|