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

plugins/input: filecount: Support resolution of symlinks in directory tree #6735

Merged
merged 3 commits into from
Dec 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions plugins/inputs/filecount/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ Reports the number and total size of files in specified directories.
## Only count regular files. Defaults to true.
regular_only = true

## Follow all symlinks while walking the directory tree. Defaults to false.
follow_symlinks = false

## Only count files that are at least this size. If size is
## a negative number, only count files that are smaller than the
## absolute value of size. Acceptable units are B, KiB, MiB, KB, ...
Expand Down
46 changes: 26 additions & 20 deletions plugins/inputs/filecount/filecount.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const sampleConfig = `
## Only count regular files. Defaults to true.
regular_only = true
## Follow all symlinks while walking the directory tree. Defaults to false.
follow_symlinks = false
## Only count files that are at least this size. If size is
## a negative number, only count files that are smaller than the
## absolute value of size. Acceptable units are B, KiB, MiB, KB, ...
Expand All @@ -48,17 +51,18 @@ const sampleConfig = `
`

type FileCount struct {
Directory string // deprecated in 1.9
Directories []string
Name string
Recursive bool
RegularOnly bool
Size internal.Size
MTime internal.Duration `toml:"mtime"`
fileFilters []fileFilterFunc
globPaths []globpath.GlobPath
Fs fileSystem
Log telegraf.Logger
Directory string // deprecated in 1.9
Directories []string
Name string
Recursive bool
RegularOnly bool
FollowSymlinks bool
Size internal.Size
MTime internal.Duration `toml:"mtime"`
fileFilters []fileFilterFunc
globPaths []globpath.GlobPath
Fs fileSystem
Log telegraf.Logger
}

func (_ *FileCount) Description() string {
Expand Down Expand Up @@ -208,6 +212,7 @@ func (fc *FileCount) count(acc telegraf.Accumulator, basedir string, glob globpa
Callback: walkFn,
PostChildrenCallback: postChildrenFn,
Unsorted: true,
FollowSymbolicLinks: fc.FollowSymlinks,
ErrorCallback: func(osPathname string, err error) godirwalk.ErrorAction {
if os.IsPermission(errors.Cause(err)) {
fc.Log.Debug(err)
Expand Down Expand Up @@ -292,15 +297,16 @@ func (fc *FileCount) initGlobPaths(acc telegraf.Accumulator) {

func NewFileCount() *FileCount {
return &FileCount{
Directory: "",
Directories: []string{},
Name: "*",
Recursive: true,
RegularOnly: true,
Size: internal.Size{Size: 0},
MTime: internal.Duration{Duration: 0},
fileFilters: nil,
Fs: osFS{},
Directory: "",
Directories: []string{},
Name: "*",
Recursive: true,
RegularOnly: true,
FollowSymlinks: false,
Size: internal.Size{Size: 0},
MTime: internal.Duration{Duration: 0},
fileFilters: nil,
Fs: osFS{},
}
}

Expand Down
14 changes: 13 additions & 1 deletion plugins/inputs/filecount/filecount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ func TestSizeFilter(t *testing.T) {
}

func TestMTimeFilter(t *testing.T) {

mtime := time.Date(2011, time.December, 14, 18, 25, 5, 0, time.UTC)
fileAge := time.Since(mtime) - (60 * time.Second)

Expand All @@ -119,6 +118,19 @@ func TestMTimeFilter(t *testing.T) {
fileCountEquals(t, fc, len(matches), 0)
}

// The library dependency karrick/godirwalk completely abstracts out the
// behavior of the FollowSymlinks plugin input option. However, it should at
// least behave identically when enabled on a filesystem with no symlinks.
func TestFollowSymlinks(t *testing.T) {
fc := getNoFilterFileCount()
fc.FollowSymlinks = true
matches := []string{"foo", "bar", "baz", "qux",
"subdir/", "subdir/quux", "subdir/quuz",
"subdir/nested2", "subdir/nested2/qux"}

fileCountEquals(t, fc, len(matches), 5096)
}

// Paths with a trailing slash will not exactly match paths produced during the
// walk as these paths are cleaned before being returned from godirwalk. #6329
func TestDirectoryWithTrailingSlash(t *testing.T) {
Expand Down