-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Add input plugin for monit #6850
Add input plugin for monit #6850
Conversation
plugins/inputs/monit/monit.go
Outdated
Address string | ||
BasicAuthUsername string | ||
BasicAuthPassword string | ||
parser parsers.Parser |
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.
Remove parser, unused.
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.
Done. Please check.
plugins/inputs/monit/monit.go
Outdated
basic_auth_username = "" | ||
basic_auth_password = "" |
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.
Call these basic_username
and basic_password
, or just username
and password
. This is to keep in line with existing plugins.
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.
Done. Please check.
plugins/inputs/monit/monit.go
Outdated
func (m *Monit) SetParser(parser parsers.Parser) { | ||
m.parser = parser | ||
} |
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.
Remove, unused.
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.
Done. Please check.
plugins/inputs/monit/monit.go
Outdated
Address string | ||
BasicAuthUsername string | ||
BasicAuthPassword 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.
On all the exported fields, add a struct tag for the toml:
Address string `toml:"address"`
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.
Done. Please check.
plugins/inputs/monit/monit.go
Outdated
decoder := xml.NewDecoder(resp.Body) | ||
decoder.CharsetReader = charset.NewReaderLabel | ||
if err := decoder.Decode(&status); err != nil { | ||
return fmt.Errorf("Cannot parse input with error: %v\n", err) |
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.
Adjust error string to match Go style guideline, the format string should be something like:
"error parsing input: %v"
https://github.com/golang/go/wiki/CodeReviewComments#error-strings
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.
Done. Please check.
plugins/inputs/monit/monit.go
Outdated
} else if service.Type == "7" { | ||
fields["last_started_time"] = service.Program.Started * 1000 | ||
fields["program_status"] = service.Program.Status | ||
fields["output"] = service.Program.Output |
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.
Is this the program output? If so we should probably skip this item due to potential length. If we would like to keep it then we need to convert/verify that the output is UTF-8 encoded and that the output isn't too large.
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.
Done. Please check
plugins/inputs/monit/monit.go
Outdated
fields["mem_kb_total"] = service.Memory.KilobyteTotal | ||
fields["mem_percent"] = service.Memory.Percent | ||
fields["mem_percent_total"] = service.Memory.PercentTotal | ||
fields["service_uptime"] = service.Uptime |
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.
Make time units consistent with other time fields.
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.
Done. Please check
plugins/inputs/monit/monit.go
Outdated
func monitoringMode(s Service) string { | ||
switch s.MonitorMode { | ||
case 0: | ||
return "Monitoring in Active mode" |
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 suggest we make these strings consistent with the Monit web interface, in mine:
Monitoring status: Monitored
Monitoring mode: active
We should try to be consistent like this in any string conversions.
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.
Done. Please check
plugins/inputs/monit/monit.go
Outdated
fields["status"] = serviceStatus(service) | ||
fields["monitoring_status_code"] = service.MonitoringStatus | ||
fields["monitoring_status"] = monitoringStatus(service) | ||
fields["monitoring_mode_status"] = monitoringMode(service) |
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.
monitoring_mode
to match web interface
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.
Done. Please check
plugins/inputs/monit/monit.go
Outdated
fields["status_code"] = service.Status | ||
fields["status"] = serviceStatus(service) | ||
fields["monitoring_status_code"] = service.MonitoringStatus | ||
fields["monitoring_status"] = monitoringStatus(service) |
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.
Let's make status
, monitoring status
and monitoring mode
as tags.
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.
Done. Please check
Aligning code to telegraf standards and added some more testcases Co-authored-by: sirishagopigiri <[email protected]> Co-authored-by: susancoombs <[email protected]>
Aligning code to telegraf standards and added some more testcases Co-authored-by: sirishagopigiri <[email protected]> Co-authored-by: susancoombs <[email protected]>
…iri/telegraf into feature/monitplugin
Co-authored-by: SirishaGopigiri <[email protected]> Co-authored-by: susancoombs <[email protected]>
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.
Here are a few more ideas, mostly around naming, that I think we should do.
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
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.
When setting up the Monit HTTPD server, you can use the ALLOW option to limit who can connect to the server. Let's add a test if possible and make sure we provide a good error message should the plugin hit this case.
plugins/inputs/monit/monit.go
Outdated
} else if s.Link.Duplex == 0 { | ||
return "Simplex Mode" | ||
} else { | ||
return "Unknown Mode" |
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.
Have the strings be: "duplex", "simplex", "unknown"
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.
Done
plugins/inputs/monit/monit.go
Outdated
case 1: | ||
return "Monitoring mode: passive" | ||
} | ||
return "Monitoring mode: unknown" |
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.
Have the strings be "active", "passive", "unknown". This is consistent with the terminology of Monit without being too repetitive with the tag 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.
Done
plugins/inputs/monit/monit.go
Outdated
case 4: | ||
return "Monitoring status: Waiting" | ||
} | ||
return "Monitoring status: Not monitored" |
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.
"monitored", "initializing", "waiting", "not_monitored"
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.
Done
plugins/inputs/monit/monit.go
Outdated
func serviceStatus(s Service) string { | ||
var status string | ||
|
||
if s.MonitoringStatus == 0 || s.MonitoringStatus == 2 { |
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.
To avoid combining the meaning of multiple fields, we should just directly report from the status. So this function could return "running" or "failure".
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.
Done
plugins/inputs/monit/monit.go
Outdated
tags := map[string]string{"address": m.Address, | ||
"version": status.Server.Version, | ||
"hostname": status.Server.LocalHostname, | ||
"platform_name": status.Platform.Name} |
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.
Remove the address
tag, and rename the hostname
tag to "source". This will be consistent with #4413.
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.
Done
plugins/inputs/monit/monit.go
Outdated
fields["swap_percent"] = service.System.Swap.Percent | ||
acc.AddFields("monit_system", fields, tags) | ||
} else if service.Type == fifo { | ||
fields["permissions"] = service.Mode |
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.
Call this mode
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.
Done
plugins/inputs/monit/monit.go
Outdated
fields["permissions"] = service.Mode | ||
acc.AddFields("monit_fifo", fields, tags) | ||
} else if service.Type == program { | ||
fields["last_started_time"] = service.Program.Started * 10000000 |
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.
Call this field program_started
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.
Done
plugins/inputs/monit/monit.go
Outdated
acc.AddFields("monit_directory", fields, tags) | ||
} else if service.Type == file { | ||
fields["size"] = service.Size | ||
fields["permissions"] = service.Mode |
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.
Call this field mode
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.
Done
Co-authored-by: SirishaGopigiri <[email protected]> Co-authored-by: susancoombs <[email protected]>
- monitoring_status | ||
- monitoring_mode | ||
|
||
### Measurements & Fields: |
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.
L31-33 looks like leftover boilerplate that needs to be deleted. Measurements and Fields are covered below
- monitoring_mode_code | ||
|
||
### Measurement & Fields: | ||
Fields for Monit service type Filesystem: |
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.
Filesystem shouldn't be capitalized if other service types aren't
Timeout internal.Duration `toml:"timeout"` | ||
} | ||
|
||
type HTTPClient interface { |
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 like that you mock http responses, but there's a simpler way to do it that is built in to http.Client. Before calling your http.Client's .Do(), you set its Transport to a custom http.RoundTripper.
I'd prefer to remove this HTTPClient interface and use a custom RoundTripper because it requires less code and because it's standard Go so it will be easier for whoever works on this code later.
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.
Thank you for the comments Reimda. I have written some sample code around RoundTripper. Could you please check?
type transportMock struct {
errorString string
}
func newTransportMock(errorString string) http.RoundTripper {
return &transportMock{
errorString: errorString,
}
}
func (t *transportMock) RoundTrip(r *http.Request) (*http.Response, error) {
return nil, errors.New(t.errorString)
}
func TestAllowHosts(t *testing.T) {
networkError := "Get http://127.0.0.1:2812/_status?format=xml: " +
"read tcp 192.168.10.2:55610->127.0.0.1:2812: " +
"read: connection reset by peer"
r := &Monit{
Address: "http://127.0.0.1:2812",
Username: "test",
Password: "test",
client: &http.Client{}
}
var acc testutil.Accumulator
r.client.Transport = newTransportMock(networkError)
err := r.Gather(&acc)
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "read: connection reset by peer")
}
}
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.
That's the idea. Also change Monit.client to be a http.Client, not a *http.Client, so you don't have to explicitly initialize it. I'd probably make type transportMock an empty struct and put the networkError string right in the RoundTrip func. Then you don't need newTransportMock either.
Looks like we already merged this PR. If you want to make a new PR to change this, feel free to add me as a reviewer.
thanks
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.
Thank you for the comments. I have raised a new PR. Could you please review?
#6955
closes #230
Required for all PRs: