-
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
Center more functionality around RunnerFactory #16715
Conversation
pipeline beat.Pipeline, | ||
factory cfgfile.RunnerFactory, | ||
selector EventSelector, | ||
configurer EventConfigurer, |
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.
selector/configurer are the same for all Beats. How about removing these altogether? I did only introduce them to keep the overall flexiblity that the Adapter did provide. @exekias Is there a reason/use-case to not remove those?
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.
I cannot think of any current use case so +1 to removing these. We can always add it when we need it
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.
How would they be removed -- does this mean that queryConfigFrom
is the only implementor of EventConfigurer
, and we can remove the interface and simply refer to the concrete struct? Or are you saying that the concrete type is also somehow redundant and we can remove this parameter entirely? Removing the interface would certainly resolve the associated documentation concerns, so I'm inclined to be in favor of it :-)
Does "selector" mean the same thing as "configurer" in this context or are you referring to two different values?
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.
Checking all Beats code the implementation is always the same. The Configurer
always returns []string{ "config" }
, and the selector always reads the field event["config"]
. In this sense the configurer and selector need to be configured together to be sound. I already combined the two into one interface in this PR. But given that all call sides always use "config"
, I'm thinking to remove the interfaces completely.
I like how interfaces are converging into a single runner factory! |
a5ca9f2
to
6508e5b
Compare
6508e5b
to
b4fd960
Compare
Note: linux build all green, windows all failing during setup. |
Jenkins, test this. |
b80adb4
to
cf8610e
Compare
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.
Various comments, mostly documentation-related :-)
} | ||
|
||
} | ||
|
||
if c.inputReloader != 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.
will c.inputReloader
ever be non-nil when crawler.Start
is called, or is it always initialized from this function?
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 will be nil if input reloading has not been enabled. I just moved the check down here, so we do not leak the go-routine in case of startup going wrong when the module loader is faulty.
libbeat/cfgfile/factories.go
Outdated
type multiplexedFactory []FactoryMatcher | ||
|
||
// FactoryMatcher returns a RunnerFactory that should be used to | ||
// handle the given configuration. |
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.
Clarify that it's intended that this will return nil in normal operation? E.g. A FactoryMatcher returns a RunnerFactory that can handle the given configuration if it supports it, otherwise it returns nil.
|
||
var errConfigDoesNotMatch = errors.New("config does not match accepted configurations") | ||
|
||
// MultiplexedRunnerFactory is a RunnerFactory that uses a list of |
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.
Uses the list how? It looks like it chooses the first match in the ordered list, if one exists, but please document the intent for callers.
libbeat/cfgfile/factories.go
Outdated
return multiplexedFactory(matchers) | ||
} | ||
|
||
// MatchHasField returns the configured RunnerFactory if the configation contains the configured field. |
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 the language here be clarified? I think I understand the intent, but MatchHasField
returns a FactoryMatcher
not a RunnerFactory
. E.g. (if I understand the intent correctly): MatchHasField returns a FactoryMatcher that returns the given RunnerFactory when the input config contains the given field name.
libbeat/cfgfile/factories.go
Outdated
} | ||
} | ||
|
||
// MatchDefault always returns the configured runner factory. |
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.
as above, "...returns a FactoryMatcher that always..."
libbeat/autodiscover/autodiscover.go
Outdated
|
||
// EventFilter returns the bus filter to retrieve runner start/stop triggering events | ||
// EventConfigurer generates a valid list of configs from the given event, the | ||
// received event will have all keys defined by `StartFilter`. |
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.
I can't find any other instance of StartFilter
in the repo, does this mean to say EventFilter
?
Also, can you clarify what is actually done to the event? Does a call to CreateConfig
modify its input, or just create new common.Config
s based on it? Are the raw strings returned by EventFilter
added as top-level keys of the event's MapStr
structure, or to the output configs, or something else?
// EventFilter returns the bus filter to retrieve runner start/stop triggering events | ||
// EventConfigurer generates a valid list of configs from the given event, the | ||
// received event will have all keys defined by `StartFilter`. | ||
type EventConfigurer interface { | ||
EventFilter() []string |
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.
Please document EventFilter
(it looks like you removed an existing doc comment, but even if it was restored it's not obvious to me how a list of strings represents a "bus filter").
pipeline beat.Pipeline, | ||
factory cfgfile.RunnerFactory, | ||
selector EventSelector, | ||
configurer EventConfigurer, |
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.
How would they be removed -- does this mean that queryConfigFrom
is the only implementor of EventConfigurer
, and we can remove the interface and simply refer to the concrete struct? Or are you saying that the concrete type is also somehow redundant and we can remove this parameter entirely? Removing the interface would certainly resolve the associated documentation concerns, so I'm inclined to be in favor of it :-)
Does "selector" mean the same thing as "configurer" in this context or are you referring to two different values?
libbeat/autodiscover/eventselect.go
Outdated
func (q queryConfigFrom) CreateConfig(e bus.Event) ([]*common.Config, error) { | ||
config, ok := e[string(q)].([]*common.Config) | ||
if !ok { | ||
return nil, errors.New("Got a wrong value in event `config` key") |
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 this error be more specific? E.g. "Event field {string(q)} does not contain a valid common.Config"
libbeat/cfgfile/reload.go
Outdated
} | ||
|
||
// ConfigChecker is usually combined with a RunnerFactory for implementations that can check a config | ||
// without a pipeline and metadata. | ||
// ConfigChecker is usually combined with a RunnerFactory for implementations |
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.
Are there any uses of ConfigChecker
without RunnerFactory
? The only references I can find are casts of RunnerFactory
to ConfigChecker
, which should be redundant with this change. Can we move CheckConfig
into RunnerFactory
and remove ConfigChecker
entirely, or is it still needed for something?
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.
will have a look and remove casts.
Remove CheckableRunnerFactory and require RunnerFactory to implement CheckConfig. CheckableRunnerFactory more and more superseded RunnerFactory. As we want more config validation support in the future as well I combined the two into RunnerFactory Remove autodiscover.Adapter. The adapter did inherit from CheckableRunnerFactory, giving us some inheritance chain between RunnerFactory, CheckableRunnerFactory, and Adapter for autodiscovery. By removig the Adapter and CheckableRunnerFactory we have one common type (RunnerFactory) to integrate with config file reloading, static input/module setup, and autodiscovery. Add selectors for autodiscovery event selection that are used as additional parameters when creating a new Autodiscover instance. This gives us some more composability, yet I wonder if we can even remove those, as every instance of NewAutodiscover did look for events with a 'config' field of type []*common.Config.
- wrap errors to give some context which operation failed - do not leak inputloader background process if configuration fails
cf8610e
to
83a4471
Compare
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.
Looks good, thanks!
All related tests did pass. |
* Center more functionality around RunnerFactory Remove CheckableRunnerFactory and require RunnerFactory to implement CheckConfig. CheckableRunnerFactory more and more superseded RunnerFactory. As we want more config validation support in the future as well I combined the two into RunnerFactory Remove autodiscover.Adapter. The adapter did inherit from CheckableRunnerFactory, giving us some inheritance chain between RunnerFactory, CheckableRunnerFactory, and Adapter for autodiscovery. By removig the Adapter and CheckableRunnerFactory we have one common type (RunnerFactory) to integrate with config file reloading, static input/module setup, and autodiscovery. Add selectors for autodiscovery event selection that are used as additional parameters when creating a new Autodiscover instance. This gives us some more composability, yet I wonder if we can even remove those, as every instance of NewAutodiscover did look for events with a 'config' field of type []*common.Config. (cherry picked from commit 7a1b524)
Co-authored-by: Steffen Siering <steffen.siering@elastic.co>
…8853) Since metricbeat light modules support processors (#15923), module initialization requires a publisher in the beat so modules can attach their processors. `metricbeat test modules` is not initializing as normal metricbeat commands, and it is not initializing any output or publisher pipeline, so metricbeat panics when trying to initialize modules with the new method. This change adds a dummy publisher for this case, and fixes also a condition that was adding a `nil` module option, causing additional panics. A test that reproduced the issues is also added. (cherry picked from commit 25b8bf1) Add nil pipeline from #16715, required for the fix. (cherry picked from commit 7a1b524) Co-authored-by: Steffen Siering <steffen.siering@elastic.co>
…es` (elastic#18853) Since metricbeat light modules support processors (elastic#15923), module initialization requires a publisher in the beat so modules can attach their processors. `metricbeat test modules` is not initializing as normal metricbeat commands, and it is not initializing any output or publisher pipeline, so metricbeat panics when trying to initialize modules with the new method. This change adds a dummy publisher for this case, and fixes also a condition that was adding a `nil` module option, causing additional panics. A test that reproduced the issues is also added. (cherry picked from commit 316793d) Add nil pipeline from elastic#16715, required for the fix. (cherry picked from commit 257fdfc) Co-authored-by: Steffen Siering <steffen.siering@elastic.co>
What does this PR do?
Remove CheckableRunnerFactory and require RunnerFactory to implement
CheckConfig. CheckableRunnerFactory more and more superseded
RunnerFactory. As we want more config validation support in the future
as well I combined the two into RunnerFactory
Remove autodiscover.Adapter. The adapter did inherit from
CheckableRunnerFactory, giving us some inheritance chain between
RunnerFactory, CheckableRunnerFactory, and Adapter for autodiscovery.
By removig the Adapter and CheckableRunnerFactory we have one common
type (RunnerFactory) to integrate with config file reloading, static
input/module setup, and autodiscovery.
Add selectors for autodiscovery event selection that are used as
additional parameters when creating a new Autodiscover instance. This
gives us some more composability, yet I wonder if we can even remove those,
as every instance of NewAutodiscover did look for events with a 'config'
field of type []*common.Config. @exekias WDYT?
Why is it important?
The new input API will have a compatiblity layer creating a RunnerFactory. By having only one interface to integrate with, the integration will be more straight forward.
The change also makes it more clear how to integrate with autodiscovery and config file reloading, as it standardizes the two based on RunnerFactory only.
Checklist
- [ ] I have made corresponding changes to the documentation- [ ] I have made corresponding change to the default configuration filesDeveloper Docs
The types
autodiscovery.Adapter
andcfgfile.CheckableRunnerFactory
have been removed. Helpers for creatingautodiscovery.Adapter
have been removed as well. Insteadcfgfile.RunnerFactory
requiresCheckConfig
to be implemented now.cfgfile.CheckableRunnerFactory
andcfgfile.Runner
factory have been combined, whereas theAdapter
is split intocfgfile.RunnerFactory
andautodiscover.EventConfigurer
. Theautodiscover.NewAutodiscover
call now needs both, theRunnerFactory
andEventConfigurer
parameters.The
(cfgfile.RunnerFactory).Create
method now accepts abeat.PipelineConnector
instead of abeat.Pipeline
as first parameter.For example:
has become:
It is assumed that CheckConfig returns an error if the configuration does not apply. In case the factory did not support CheckConfig before, the functionality needs to be implemented like this: