-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Experimental go 1.8 plugin support #3217
Conversation
That means that the exact same libbeat version needs to be used when compiling both the Beat and the plugin? |
Right. Plus compiler version, as runtime is also included in plugin. |
@@ -155,6 +156,10 @@ func (b *Beat) launch(bt Creator) error { | |||
return err | |||
} | |||
|
|||
if err := plugin.Initialize(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we "hide" this behind a config option something like plugins.enabled: false
? This make sure nothing happens by default and will make it easier to mark this experimential. Especially as it is not supported on all platforms and only go 1.8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Plugins are loadable from CLI only using the -plugin
setting. No config file support yet, as feature is very experimental.
Only if plugin support is available, the flag will be available. The Initialize function is implemented in cli.go. In case no plugin support is available cli_stub.go will be used (empty function).
This behavior close enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The behaviour is the same. It's just that with a undocument config option, not even the initialize code would be execute. I would still prefer to have an additional config option :-)
constr Constructor | ||
} | ||
|
||
var pluginKey = "libbeat-processor" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we use the dot notation for the keys as we do in most other places? Means libbeat.processor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't really matter, as the pluginKey is private to the package providing a plugin type. It's only required for them to be 'unique'. We could even use a generated UUID.
jenkins, test it |
- requires linux, go1.8 and cgo - plugins export a `Bundle` symbol of type `map[string][]interface{}`. The `key` is special to every pluggable module in beats - all pluggable beats modules provide a `PluginX` function to create a valid bundle - using `plugin.Bundle`, multiple bundles can be combined into one. A bundle can contain plugins for different beats and be loaded by all these different beats. - plugins can be loaded via CLI only using the `-plugin <path>` flag - add plugin support for: - libbeat outputs - libbeat processors - packetbeat protocol analyzers - metricbeat modules - heartbeat monitors See PR elastic#3217 for more details
This PR introduces support for loadable plugins to beats. Requires linux, go1.8 beta2+, cgo. If any is missing, the API is still valid, but plugin loading is disabled (CLI flag is missing as well).
Shared libraries export a bundle of plugins in global
Bundle
variable of typemap[string][]interface{}
. Thestring
key is the plugin module type, individual plugins are loadable for.Beats modules supporting plugin support have to register a module type before startup via
plugin.RegisterLoader
. In addition modules must provide aPlugin
function for building a valid type-correct bundle with correct module type key. Seeoutputs.Plugin
andprocessors.Plugin
as example.Alternatively a solution with
Bundle
of type[]interface{}
orinterface{}
might be possible too (no potential naming collisions). Loading can use reflection and/or type switches. This might work, by passing all loadable plugins to all module loaders. With public API as is, this implementation detail can be easily applied later without enforcing any changes on plugin writers.Every plugin is a valid bundle itself. Use
plugin.Bundle
to flatten and combine multiple bundles/plugins into one bundle.Bundles can be loaded from command line only. Use
-plugin <path>
to load a plugin.Versioning: the plugin loader does no explicit version checks. A possible solution is to have
plugin.Bundle
include a version and be strict (e.g. on major version). On the other hand, the compiler already hashes all packages. The runtime already ensures no plugin with failing hash-check can be used.thisnPR adds plugin support for: