From 07728d742529c96dfcc4f77a3123cfca9b283938 Mon Sep 17 00:00:00 2001 From: Cameron Sparr Date: Sun, 24 Apr 2016 14:37:44 -0600 Subject: [PATCH] Refactor globpath pkg to return a map this is so that we don't call os.Stat twice for every file matched by Match(). Also changing the behavior to _not_ return the name of a file that doesn't exist if it's not a glob. --- internal/globpath/globpath.go | 17 +++++++++----- internal/globpath/globpath_test.go | 13 +++++++++++ plugins/inputs/filestat/filestat.go | 36 ++++++++++++++--------------- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/internal/globpath/globpath.go b/internal/globpath/globpath.go index 729754063..6755e69b2 100644 --- a/internal/globpath/globpath.go +++ b/internal/globpath/globpath.go @@ -39,20 +39,25 @@ func Compile(path string) (*GlobPath, error) { return &out, nil } -func (g *GlobPath) Match() []string { +func (g *GlobPath) Match() map[string]os.FileInfo { if !g.hasMeta { - return []string{g.path} + out := make(map[string]os.FileInfo) + info, err := os.Stat(g.path) + if !os.IsNotExist(err) { + out[g.path] = info + } + return out } return walkFilePath(g.root, g.g) } // walk the filepath from the given root and return a list of files that match // the given glob. -func walkFilePath(root string, g glob.Glob) []string { - matchedFiles := []string{} - walkfn := func(path string, _ os.FileInfo, _ error) error { +func walkFilePath(root string, g glob.Glob) map[string]os.FileInfo { + matchedFiles := make(map[string]os.FileInfo) + walkfn := func(path string, info os.FileInfo, _ error) error { if g.Match(path) { - matchedFiles = append(matchedFiles, path) + matchedFiles[path] = info } return nil } diff --git a/internal/globpath/globpath_test.go b/internal/globpath/globpath_test.go index 9c3fc16e0..db72c94f4 100644 --- a/internal/globpath/globpath_test.go +++ b/internal/globpath/globpath_test.go @@ -11,12 +11,21 @@ import ( func TestCompileAndMatch(t *testing.T) { dir := getTestdataDir() + // test super asterisk g1, err := Compile(dir + "/**") require.NoError(t, err) + // test single asterisk g2, err := Compile(dir + "/*.log") require.NoError(t, err) + // test no meta characters (file exists) g3, err := Compile(dir + "/log1.log") require.NoError(t, err) + // test file that doesn't exist + g4, err := Compile(dir + "/i_dont_exist.log") + require.NoError(t, err) + // test super asterisk that doesn't exist + g5, err := Compile(dir + "/dir_doesnt_exist/**") + require.NoError(t, err) matches := g1.Match() assert.Len(t, matches, 3) @@ -24,6 +33,10 @@ func TestCompileAndMatch(t *testing.T) { assert.Len(t, matches, 2) matches = g3.Match() assert.Len(t, matches, 1) + matches = g4.Match() + assert.Len(t, matches, 0) + matches = g5.Match() + assert.Len(t, matches, 0) } func TestFindRootDir(t *testing.T) { diff --git a/plugins/inputs/filestat/filestat.go b/plugins/inputs/filestat/filestat.go index 6e61a0a5f..831d37444 100644 --- a/plugins/inputs/filestat/filestat.go +++ b/plugins/inputs/filestat/filestat.go @@ -55,31 +55,29 @@ func (f *FileStat) Gather(acc telegraf.Accumulator) error { f.globs[filepath] = g } - for _, file := range g.Match() { + files := g.Match() + if len(files) == 0 { + acc.AddFields("filestat", + map[string]interface{}{ + "exists": int64(0), + }, + map[string]string{ + "file": filepath, + }) + continue + } + + for fileName, fileInfo := range files { tags := map[string]string{ - "file": file, + "file": fileName, } fields := map[string]interface{}{ - "exists": int64(0), + "exists": int64(1), + "size_bytes": fileInfo.Size(), } - // Get file stats - fileInfo, err := os.Stat(file) - if os.IsNotExist(err) { - // file doesn't exist, so move on to the next - acc.AddFields("filestat", fields, tags) - continue - } - if err != nil { - errS += err.Error() + " " - continue - } - - // file exists and no errors encountered - fields["exists"] = int64(1) - fields["size_bytes"] = fileInfo.Size() if f.Md5 { - md5, err := getMd5(file) + md5, err := getMd5(fileName) if err != nil { errS += err.Error() + " " } else {