-
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
Metricbeat Prototype #611
Metricbeat Prototype #611
Conversation
Community Metricbeat ModulesOver time the discussion will come up which metrics we maintain from the elastic side and which ones should be maintained by the community. To solve this issue I propose the following solution. There are two versions of metricbeat, the version supported by elastic and the community version. The community version fully depends on the supported version except for the modules and metrics. It lives in it's on repository for example under elastic/metricbeat-community. The only requirement is that there are no name conflicts between the modules of the two metricbeats. The modules in the community versions could also be maintained by community contributors. In addition we could have an "incubation" phase to also migrate some of the modules over time from the community beat into our own beat. Here is a working prototype branch of the metricbeat-community: https://github.com/ruflin/beats/tree/metricbeat-community/metricbeat-community Note: This branch is just as an example and is not intended to be merged The same concept could also be applied to protocols in packetbeat. |
_ "github.com/elastic/beats/metricbeat/module/elasticsearch/cluster-stats" | ||
_ "github.com/elastic/beats/metricbeat/module/elasticsearch/info" | ||
_ "github.com/elastic/beats/metricbeat/module/elasticsearch/stats" | ||
_ "github.com/elastic/beats/metricbeat/module/redis/info" |
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.
Another option here would be to just import the module and let the module import the metrics. Not sure which way is more maintainable, just figured I mention the option for discussion.
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.
This would definitively be nicer as this list here would have to be updated less frequently and it imports would be more local. I tried this first but it doesn't work because of cyclic imports. As I designed metricbeat so far that a MetricSet registers with the module and the module doesn't know in advance about all the MetricSets, the MetricSet imports its module. Not sure if there is a way around the cyclic imports to make it mor maintainable. An other option could be to automatically generate this list.
Another thing that we'll need is a way for each module to generate JSON for the Elasticsearch template. |
|
||
// Set type from event if set | ||
if _, ok := event["type"]; ok { | ||
typeName = event["type"].(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.
Would be worth checking the type assertion (typeName, ok = event["type"].(string)
) to avoid a run time panic.
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 think we will need a way to add custom fields not only by module and metric, but also on a per "host" basis. For example, if one wants to monitor multiple Redis servers, they would need to add some fields to the events to know which events refer to each hosts. Perhaps it would be worth making the |
} | ||
|
||
func Connect() redis.Conn { | ||
conn, err := redis.Dial("tcp", "127.0.0.1:6379") |
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.
Obviously a bit simplistic here :-).
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.
Prototype ;-)
type RawMetricsConfig struct { | ||
Metricbeat struct { | ||
Modules map[string]struct { | ||
MetricSets map[string]interface{} `yaml:"metricsets"` |
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.
this is common.MapStr right?
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.
Good point, it is :-)
May I ask if the community version is compiled as one binary called "metricbeat" or multiple binaries? |
@mrkschan That is a good question. It is one binary as you can add support for another service in Metricbeat by adding a new module. |
So, would that be bloated (eventually) and would it be possible that dependency of one service is having conflict with another? |
The goal is to keep this as lightweight as possible and also to keep the module as independent as possible. This means, at any time it should be possible to only build on module and for example in the case of redis, only have a redisbeat. Of course, this doesn't mean there won't be any conflicts with dependency. I'm tempted to say we solve it when we get there. Do you have any specific library in mind? |
@ruflin, i don't get what do you mean by building one module. Do you mean we will have some scripts to generate a Re: conflicts. I don't have any idea which library would introduce conflict with another so far, though, I can foresee backward incompatibility of a particular library in the future. |
@mrkschan Here is an example I built some weeks ago. It is not up-to-date anymore but should give you and understand of what I mean: https://github.com/ruflin/beats/tree/metricbeat-community/metricbeat-community. Just assume it would be called redisbeat and the module would be redis. Please be aware that most of these points are still under discussion. Which particular library are you referring to? |
0304766
to
d7aa431
Compare
16e3618
to
f4800cd
Compare
func TestFetch(t *testing.T) { | ||
|
||
if testing.Short() { | ||
t.Skip("Skipping in short mode, because it requires Redis") |
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.
s/Redis/Mysql
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.
(fixed, multiple times ...)
I'm good with merging at this point. Thanks @ruflin for driving it up to here! |
899b301
to
330a6ff
Compare
This is the first basic implementation of MetricBeat. For more details on what it contains, check below. = MetricSets The following basic MetricSet are part of this first version. * Apache module with Apache status * Redis module with Redis info * MySQL module with status Be aware that only very few metrics are collected per MetricSet, but more could be added easily = Data Model The current data model of each metricset can be found in the file beater/metricbeat.go in the header docs. = Error Handling It is assumed, that a module or metricset can panic. This panic is catched to not kill all other modules. This error is reported in the log files. The failing module / metricset will not be restarted = Configuration Each module and metricSet can have its own configuration. The following fields are generic configurations per module and are always available: * Period * Hosts More details can be found in etc/beat.yml = Testing * Golang test framework for unit tests * Golang test framework combined with docker-compose for integration tests * Python libbeat system test framework combined with docker-compose for system tests All tests are intended to be run inside the docker environment. = Vendoring The prevent dependency conflicts between modules, each module can have its own vendor environment. This is implemented as an example in the MySQL module.
This is a working prototype of Metricbeat. This PR is intended to discuss the prototype and get it to a mergeable state. See #619
Currently it has the following metrics as examples:
Todo
The following things are not implemented yet and have to be done before merging (or a separate issue has to be opened):