forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 5
/
postfix.go
111 lines (96 loc) · 2.36 KB
/
postfix.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package postfix
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/inputs"
)
const sampleConfig = `
## Postfix queue directory. If not provided, telegraf will try to use
## 'postconf -h queue_directory' to determine it.
# queue_directory = "/var/spool/postfix"
`
const description = "Measure postfix queue statistics"
func getQueueDirectory() (string, error) {
qd, err := exec.Command("postconf", "-h", "queue_directory").Output()
if err != nil {
return "", err
}
return strings.TrimSpace(string(qd)), nil
}
func qScan(path string, acc telegraf.Accumulator) (int64, int64, int64, error) {
var length, size int64
var oldest time.Time
err := filepath.Walk(path, func(_ string, finfo os.FileInfo, err error) error {
if err != nil {
acc.AddError(fmt.Errorf("error scanning %s: %s", path, err))
return nil
}
if finfo.IsDir() {
return nil
}
length++
size += finfo.Size()
ctime := statCTime(finfo.Sys())
if ctime.IsZero() {
return nil
}
if oldest.IsZero() || ctime.Before(oldest) {
oldest = ctime
}
return nil
})
if err != nil {
return 0, 0, 0, err
}
var age int64
if !oldest.IsZero() {
age = int64(time.Now().Sub(oldest) / time.Second)
} else if length != 0 {
// system doesn't support ctime
age = -1
}
return length, size, age, nil
}
type Postfix struct {
QueueDirectory string
}
func (p *Postfix) Gather(acc telegraf.Accumulator) error {
if p.QueueDirectory == "" {
var err error
p.QueueDirectory, err = getQueueDirectory()
if err != nil {
return fmt.Errorf("unable to determine queue directory: %s", err)
}
}
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred"} {
length, size, age, err := qScan(filepath.Join(p.QueueDirectory, q), acc)
if err != nil {
acc.AddError(fmt.Errorf("error scanning queue %s: %s", q, err))
continue
}
fields := map[string]interface{}{"length": length, "size": size}
if age != -1 {
fields["age"] = age
}
acc.AddFields("postfix_queue", fields, map[string]string{"queue": q})
}
return nil
}
func (p *Postfix) SampleConfig() string {
return sampleConfig
}
func (p *Postfix) Description() string {
return description
}
func init() {
inputs.Add("postfix", func() telegraf.Input {
return &Postfix{
QueueDirectory: "/var/spool/postfix",
}
})
}