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

Allow globs in FPM unix socket paths #7089

Merged
merged 7 commits into from
Feb 28, 2020

Conversation

andrenth
Copy link
Contributor

This PR allows glob patterns to be used in the unixsocket configuration. This is useful in environments where FPM pools are managed dynamically, so that the configuration file doesn't have to be edited every time a pool is created or deleted.

Required for all PRs:

  • Signed CLA.
  • Associated README.md updated.
  • Has appropriate unit tests.

Copy link
Contributor

@ssoroka ssoroka left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!
Do we want to consider processing the list of file sockets once on startup instead of every gather request?

plugins/inputs/phpfpm/phpfpm.go Outdated Show resolved Hide resolved
Co-Authored-By: Steven Soroka <ssoroka78@gmail.com>
@andrenth
Copy link
Contributor Author

Thanks for the PR!
Do we want to consider processing the list of file sockets once on startup instead of every gather request?

Doing it on every gather would simplify things for me, as no further action would be needed to monitor/stop monitoring dynamically managed pools. Doing it on startup wouldn't be a deal breaker: I'd simply have to reload [restart?] Telegraf every time a pool is added or removed, along with the reload of the FPM daemon that I already perform.

One advantage of doing it on every gather is that it won't cause pauses in the data collection of unrelated metrics because Telegraf had to be restarted to rebuild the FPM socket list.

@ssoroka ssoroka requested a review from danielnelson February 27, 2020 18:53
Copy link
Contributor

@danielnelson danielnelson left a comment

Choose a reason for hiding this comment

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

Keeping style with some other plugins using globs, such as file,tail, etc we probably should match the glob every gather. If we use globpath.Globpath it will skip calling glob expansion if not needed.

plugins/inputs/phpfpm/phpfpm.go Outdated Show resolved Hide resolved
Comment on lines 307 to 312
if len(paths) == 0 {
_, err := os.Stat(pattern)
if os.IsNotExist(err) {
return nil, fmt.Errorf("Socket doesn't exist '%s': %s", pattern, err)
}
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'm not sure I understand this correctly, would this check for files that contain '*' characters? I feel like this is probably not needed, this seems very edge case, but either way we should consider if it should be an error to not match a socket. In the other plugins using globs, not having matches is generally not an error but this decision it can make it difficult to debug. If there are situations where it is normal to not match a socket, then it might be better to ignore the error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did it this way to keep the previous behavior, which is to error out on nonexistent socket paths. Since filepath.Glob ignores any errors other than syntax ones, I've used os.Stat to get the appropriate error. The special handling of os.ErrNotExist is there because it's also done elsewhere in the plugin.

If you think we consider that not matching any sockets is not an error, this code would indeed be a bit cleaner.

Copy link
Contributor Author

@andrenth andrenth Feb 28, 2020

Choose a reason for hiding this comment

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

One example of where this handling is useful is when the unix socket path is in fact not a glob, and the file does not exist. In that case, we'd get an empty slice of strings as a result from the glob, with no error, so this extra checking restores the error message one would get before glob support.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, let's continue to show an error when the socket doesn't exist. I think we should then remove the Stat call on L166, which doesn't seem useful anymore and anyway we will report an error afterwards connecting to the socket if it doesn't exist.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking at the globpath module I noticed Match actually returns the given parameter when it's a static path, so the latest commit handles this case correctly now. I've also removed the redundant os.Stat call.

If the PR is OK now, do you want me to rebase before merging?

Comment on lines 301 to 303
if len(paths) == 0 {
return nil, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

If we are planning to show an error if a glob doesn't have any matches, then I think we need to do it here.

Copy link
Contributor Author

@andrenth andrenth Feb 28, 2020

Choose a reason for hiding this comment

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

Hmm ok, my thinking was that since globpath can diferentiate static paths from patterns, to allow non-matching globs, but to error on static paths. But it's probably better to be consistent.

Comment on lines 305 to 314
// globpath.Match() returns the given argument when it's a static path,
// i.e., not a glob pattern. In that case, ensure it exists.
if len(paths) == 1 && paths[0] == pattern {
if _, err := os.Stat(paths[0]); err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("Socket doesn't exist '%s': %s", pattern, err)
}
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.

Since, as you mentioned, Match() will return the path if there are no special glob characters, I think we can remove this too. We will still display an error when we dial the socket.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done (this required a change to the unit tests due to the error now coming from Dial).

@danielnelson danielnelson added the feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin label Feb 28, 2020
@danielnelson danielnelson added this to the 1.14.0 milestone Feb 28, 2020
@danielnelson danielnelson merged commit 88216eb into influxdata:master Feb 28, 2020
@danielnelson
Copy link
Contributor

Merged for 1.14, thanks!

@andrenth
Copy link
Contributor Author

Thank you!

athoune pushed a commit to bearstech/telegraf that referenced this pull request Apr 17, 2020
idohalevi pushed a commit to idohalevi/telegraf that referenced this pull request Sep 29, 2020
arstercz pushed a commit to arstercz/telegraf that referenced this pull request Mar 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat Improvement on an existing feature such as adding a new setting/mode to an existing plugin
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants