diff --git a/plugins/inputs/postfix/postfix.go b/plugins/inputs/postfix/postfix.go index 02b351d78..a33879760 100644 --- a/plugins/inputs/postfix/postfix.go +++ b/plugins/inputs/postfix/postfix.go @@ -45,15 +45,23 @@ func qScan(path string) (int64, int64, int64, error) { for _, finfo := range finfos { length++ size += finfo.Size() - if oldest.IsZero() || finfo.ModTime().Before(oldest) { - oldest = finfo.ModTime() + + ctime := statCTime(finfo.Sys()) + if ctime.IsZero() { + continue + } + if oldest.IsZero() || ctime.Before(oldest) { + oldest = ctime } } - var age time.Duration + var age int64 if !oldest.IsZero() { - age = time.Now().Sub(oldest) / time.Second + age = int64(time.Now().Sub(oldest) / time.Second) + } else if len(finfos) != 0 { + // system doesn't support ctime + age = -1 } - return length, size, int64(age), nil + return length, size, age, nil } type Postfix struct { @@ -75,11 +83,15 @@ func (p *Postfix) Gather(acc telegraf.Accumulator) error { acc.AddError(fmt.Errorf("error scanning queue %s: %s", q, err)) continue } - fields := map[string]interface{}{"length": length, "size": size, "age": age} + fields := map[string]interface{}{"length": length, "size": size} + if age != -1 { + fields["age"] = age + } acc.AddFields("postfix_queue", fields, map[string]string{"queue": q}) } - var dLength, dSize, dAge int64 + var dLength, dSize int64 + dAge := int64(-1) for _, q := range []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"} { length, size, age, err := qScan(path.Join(p.QueueDirectory, "deferred", q)) if err != nil { @@ -96,7 +108,10 @@ func (p *Postfix) Gather(acc telegraf.Accumulator) error { dAge = age } } - fields := map[string]interface{}{"length": dLength, "size": dSize, "age": dAge} + fields := map[string]interface{}{"length": dLength, "size": dSize} + if dAge != -1 { + fields["age"] = dAge + } acc.AddFields("postfix_queue", fields, map[string]string{"queue": "deferred"}) return nil diff --git a/plugins/inputs/postfix/postfix_test.go b/plugins/inputs/postfix/postfix_test.go index 859d773c7..75a6817a7 100644 --- a/plugins/inputs/postfix/postfix_test.go +++ b/plugins/inputs/postfix/postfix_test.go @@ -5,7 +5,6 @@ import ( "os" "path" "testing" - "time" "github.com/influxdata/telegraf/testutil" "github.com/stretchr/testify/assert" @@ -26,7 +25,6 @@ func TestGather(t *testing.T) { require.NoError(t, ioutil.WriteFile(path.Join(td, "active", "01"), []byte("abc"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "active", "02"), []byte("defg"), 0644)) - require.NoError(t, os.Chtimes(path.Join(td, "active", "02"), time.Now(), time.Now().Add(-time.Hour))) require.NoError(t, ioutil.WriteFile(path.Join(td, "hold", "01"), []byte("abc"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "incoming", "01"), []byte("abcd"), 0644)) require.NoError(t, ioutil.WriteFile(path.Join(td, "deferred", "0", "01"), []byte("abc"), 0644)) @@ -46,7 +44,7 @@ func TestGather(t *testing.T) { assert.Equal(t, int64(2), metrics["active"].Fields["length"]) assert.Equal(t, int64(7), metrics["active"].Fields["size"]) - assert.InDelta(t, int64(time.Hour/time.Second), metrics["active"].Fields["age"], 10) + assert.InDelta(t, 0, metrics["active"].Fields["age"], 10) assert.Equal(t, int64(1), metrics["hold"].Fields["length"]) assert.Equal(t, int64(3), metrics["hold"].Fields["size"]) diff --git a/plugins/inputs/postfix/stat_ctim.go b/plugins/inputs/postfix/stat_ctim.go new file mode 100644 index 000000000..456df5ffd --- /dev/null +++ b/plugins/inputs/postfix/stat_ctim.go @@ -0,0 +1,16 @@ +// +build dragonfly linux netbsd openbsd solaris + +package postfix + +import ( + "syscall" + "time" +) + +func statCTime(sys interface{}) time.Time { + stat, ok := sys.(*syscall.Stat_t) + if !ok { + return time.Time{} + } + return time.Unix(stat.Ctim.Unix()) +} diff --git a/plugins/inputs/postfix/stat_ctimespec.go b/plugins/inputs/postfix/stat_ctimespec.go new file mode 100644 index 000000000..40e0de6cc --- /dev/null +++ b/plugins/inputs/postfix/stat_ctimespec.go @@ -0,0 +1,16 @@ +// +build darwin freebsd + +package postfix + +import ( + "syscall" + "time" +) + +func statCTime(sys interface{}) time.Time { + stat, ok := sys.(*syscall.Stat_t) + if !ok { + return time.Time{} + } + return time.Unix(stat.Ctimespec.Unix()) +} diff --git a/plugins/inputs/postfix/stat_none.go b/plugins/inputs/postfix/stat_none.go new file mode 100644 index 000000000..c5c013ce3 --- /dev/null +++ b/plugins/inputs/postfix/stat_none.go @@ -0,0 +1,7 @@ +// +build !dragonfly,!linux,!netbsd,!openbsd,!solaris,!darwin,!freebsd + +package postfix + +func statCTime(_ interface{}) time.Time { + return time.Time{} +}