-
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
Allow globs in FPM unix socket paths #7089
Changes from 6 commits
b74c7aa
bff2d92
916f1d3
a57b771
8455e2c
b177094
2a7bf89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ import ( | |
|
||
"github.com/influxdata/telegraf" | ||
"github.com/influxdata/telegraf/internal" | ||
"github.com/influxdata/telegraf/internal/globpath" | ||
"github.com/influxdata/telegraf/internal/tls" | ||
"github.com/influxdata/telegraf/plugins/inputs" | ||
) | ||
|
@@ -95,7 +96,12 @@ func (g *phpfpm) Gather(acc telegraf.Accumulator) error { | |
|
||
var wg sync.WaitGroup | ||
|
||
for _, serv := range g.Urls { | ||
urls, err := expandUrls(g.Urls) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, serv := range urls { | ||
wg.Add(1) | ||
go func(serv string) { | ||
defer wg.Done() | ||
|
@@ -153,18 +159,10 @@ func (g *phpfpm) gatherServer(addr string, acc telegraf.Accumulator) error { | |
statusPath = "status" | ||
} | ||
} else { | ||
socketAddr := strings.Split(addr, ":") | ||
if len(socketAddr) >= 2 { | ||
socketPath = socketAddr[0] | ||
statusPath = socketAddr[1] | ||
} else { | ||
socketPath = socketAddr[0] | ||
socketPath, statusPath = unixSocketPaths(addr) | ||
if statusPath == "" { | ||
statusPath = "status" | ||
} | ||
|
||
if _, err := os.Stat(socketPath); os.IsNotExist(err) { | ||
return fmt.Errorf("Socket doesn't exist '%s': %s", socketPath, err) | ||
} | ||
fcgi, err = newFcgiClient("unix", socketPath) | ||
} | ||
|
||
|
@@ -277,6 +275,75 @@ func importMetric(r io.Reader, acc telegraf.Accumulator, addr string) (poolStat, | |
return stats, nil | ||
} | ||
|
||
func expandUrls(urls []string) ([]string, error) { | ||
addrs := make([]string, 0, len(urls)) | ||
for _, url := range urls { | ||
if isNetworkURL(url) { | ||
addrs = append(addrs, url) | ||
continue | ||
} | ||
paths, err := globUnixSocket(url) | ||
if err != nil { | ||
return nil, err | ||
} | ||
addrs = append(addrs, paths...) | ||
} | ||
return addrs, nil | ||
} | ||
|
||
func globUnixSocket(url string) ([]string, error) { | ||
pattern, status := unixSocketPaths(url) | ||
glob, err := globpath.Compile(pattern) | ||
if err != nil { | ||
return nil, fmt.Errorf("could not compile glob %q: %v", pattern, err) | ||
} | ||
paths := glob.Match() | ||
if len(paths) == 0 { | ||
return nil, nil | ||
} | ||
|
||
// 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 | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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). |
||
|
||
addrs := make([]string, 0, len(paths)) | ||
|
||
for _, path := range paths { | ||
if status != "" { | ||
status = fmt.Sprintf(":%s", status) | ||
} | ||
addrs = append(addrs, fmt.Sprintf("%s%s", path, status)) | ||
} | ||
|
||
return addrs, nil | ||
} | ||
|
||
func unixSocketPaths(addr string) (string, string) { | ||
var socketPath, statusPath string | ||
|
||
socketAddr := strings.Split(addr, ":") | ||
if len(socketAddr) >= 2 { | ||
socketPath = socketAddr[0] | ||
statusPath = socketAddr[1] | ||
} else { | ||
socketPath = socketAddr[0] | ||
statusPath = "" | ||
} | ||
|
||
return socketPath, statusPath | ||
} | ||
|
||
func isNetworkURL(addr string) bool { | ||
return strings.HasPrefix(addr, "http://") || strings.HasPrefix(addr, "https://") || strings.HasPrefix(addr, "fcgi://") || strings.HasPrefix(addr, "cgi://") | ||
} | ||
|
||
func init() { | ||
inputs.Add("phpfpm", func() telegraf.Input { | ||
return &phpfpm{} | ||
|
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.
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.
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.
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.