Skip to content
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: Add munin module #6517

Merged
merged 1 commit into from
Mar 19, 2018
Merged

Metricbeat: Add munin module #6517

merged 1 commit into from
Mar 19, 2018

Conversation

jsoriano
Copy link
Member

@jsoriano jsoriano commented Mar 9, 2018

Add module to export metrics from munin nodes (#6473). It can obtain metrics from any agent that implements the basic protocol for data exchange between master and nodes. Under the terms of this protocol, metricbeat would be acting as a master.

return n, err
}

// Releases node connection resources

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported method Node.Close should be of the form "Close ..."

reader *bufio.Reader
}

// Connects with a munin node

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported function Connect should be of the form "Connect ..."

unknownValue = "U"
)

// Munin node client

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment on exported type Node should be of the form "Node ..." (with optional leading article)

@jsoriano jsoriano force-pushed the munin-module branch 5 times, most recently from 45757a0 to 441345c Compare March 10, 2018 02:18
@jsoriano
Copy link
Member Author

jenkins, test it

Copy link
Contributor

@exekias exekias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome new module! 🎉

I left some comments. It would be nice to generate an example data.json. have a look to make generate-json

continue
}
if f, err := strconv.ParseFloat(value, 64); err == nil {
event.Put(key, f)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the record, this is a candidate for safemapstr.Put: #6434 as soon as it's in

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, the PR went in already, so you can update these :)

Copy link
Member Author

@jsoriano jsoriano Mar 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, but I think dots are not allowed in munin metric names.
We could use safemapstr in any case to protect metricbeat against incorrect implementations of munin nodes or plugins, wdyt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if the float parsing will make a difference in ES. If we have a value 3 and we parse it it will still put 3 into the event and on the ES side it will assume it's an integer so conflicts will happen afterwards. Sounds like a good use case for the local fields definitions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umm, so what do you recommend to do here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've checked metrics format, sounds like we don't need safemapstr.Put here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what I'm getting at we could even skip this code part here and it would make no difference? If someone wants to make sure the mapping is correct he has to use #6024

Please double check the above statement as I don't know much about the munin output.

event.Put(key, f)
continue
}
event.Put(key, value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

safemapstr.Put too

config := struct{}{}
if err := base.Module().UnpackConfig(&config); err != nil {
return nil, err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is not needed, as there is no custom config to parse?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually there is no custom config so far, I'll remove this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have finally kept it to support namespaces.

}
// Cosume and ignore first line returned by munin, it is a comment
// about the node
bufio.NewScanner(n.reader).Scan()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we check for the return value here? In case of false we should probably check the Err method for the error.

Copy link
Member Author

@jsoriano jsoriano Mar 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I will return scanner.Error().

}

scanner := bufio.NewScanner(n.reader)
scanner.Scan()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also check here the return value?


scanner := bufio.NewScanner(n.reader)
scanner.Scan()
return strings.Fields(scanner.Text()), scanner.Err()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you run here scanner.Err() which makes the return value check obsolete before.

}

// Fetch method implements the data gathering
func (m *MetricSet) Fetch() (common.MapStr, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As if this metricset is used for different host, the returned data can contain very different structures. We should allow to set the namespace for this metricset as we do for example for the http/json metricset to make sure users can choose their namespace to prevent field conflicts.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, adding namespace.

@@ -0,0 +1,60 @@
package node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You wrote above that metricbeat is the master in this scenario so I was tempted to say we should call the default namespace master. But as it's about the data from the node (is that naming correct?) +1 on node.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Protocol-wise we are like implementing the server side, but the metrics on the metricset are about the node, so +1 too to node :)

Copy link
Member

@ruflin ruflin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Left some minor comments.

hosts: ["localhost:4949"]
---

All metrics exposed by a single munin node will be sent as an only event,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"All metrics exposed by a single munin node will be sent in a single event, grouped by munin items." ?

An example here would be nice.

metricsets: ["node"]
enabled: false
period: 10s
hosts: ["localhost:4949"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The namespace config should be an option here.

cfgwarn.Experimental("The munin node metricset is experimental.")

config := struct {
Namespace string `config:"namespace" validate:"required"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is not the case in the other implementations but we should prefix all configs with the metricset to make sure it's obvious to which metricset they belong. So this should be node.namespace.

metricsets: ["node"]
enabled: false
period: 10s
hosts: ["localhost:4949"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add namespace config.

metricsets: ["node"]
enabled: false
period: 10s
hosts: ["localhost:4949"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add namespace config

@jsoriano
Copy link
Member Author

Added namespace config where it was missing, and renamed it to node.namespace.

@jsoriano
Copy link
Member Author

I still have to take a look to the data.json generator.

@ruflin
Copy link
Member

ruflin commented Mar 16, 2018

@jsoriano I think for this metricset the data.json does not make much sense. We also skipped it for the other "dynamic" metricsets. Could you rebase again and squash your commits into one with a nice commit message?

@exekias Can you also check the PR again?

@jsoriano
Copy link
Member Author

jsoriano commented Mar 16, 2018

@ruflin, after changing from namespace to node.namespace integration test is not working, metricbeat complains about missing required field. Actually in the generated build/system-tests/last_run/metricbeat.yml I couldn't see this setting.

I have seen in the base template that it expects the namespace to be in namespace. I have had to add it in the extras to make it work:

            "extras": {
                "node.namespace": namespace,
            },

Is this ok?

Add munin module, with node metricset that obtain metrics
from a running munin node using the same protocol used by
munin masters.
@ruflin
Copy link
Member

ruflin commented Mar 19, 2018

The extras is fine to solve the CI issue.

I'm going forth and back if namespace should be prefix by the metricset or not. The reason I like to have it prefix is that we do that will all metricset specific configs. Like this it becomes obvious to which metricset it belongs and does not accidentially overlap with other metricsets configs. Probably the reason we have it globally is that "dynamic" metricsets like this one should also be configured alone, meaning that the list of metricsets enable in a module should only contain this one. We don't enforce this yet but probably should. Like this an overlap cannot happen. Having the namespace config option on the module level could allow us to make it supported in a generic way and not have to implement it in each module.

@exekias @andrewkroh Any thoughts here?

@ruflin ruflin merged commit 7756f94 into elastic:master Mar 19, 2018
@ruflin
Copy link
Member

ruflin commented Mar 19, 2018

I merged the PR to have the munin module in. The discussion about the naming of the namespace option should continue. As the module is not yet release and still experimental we can still make changes.

@jsoriano jsoriano deleted the munin-module branch March 22, 2018 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants