Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
73
plugins/inputs/postfix/README.md
Normal file
73
plugins/inputs/postfix/README.md
Normal file
|
@ -0,0 +1,73 @@
|
|||
# Postfix Input Plugin
|
||||
|
||||
The postfix plugin reports metrics on the postfix queues.
|
||||
|
||||
For each of the active, hold, incoming, maildrop, and deferred queues
|
||||
(<http://www.postfix.org/QSHAPE_README.html#queues>), it will report the queue
|
||||
length (number of items), size (bytes used by items), and age (age of oldest
|
||||
item in seconds).
|
||||
|
||||
## Global configuration options <!-- @/docs/includes/plugin_config.md -->
|
||||
|
||||
In addition to the plugin-specific configuration settings, plugins support
|
||||
additional global and plugin configuration settings. These settings are used to
|
||||
modify metrics, tags, and field or create aliases and configure ordering, etc.
|
||||
See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||
|
||||
[CONFIGURATION.md]: ../../../docs/CONFIGURATION.md#plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml @sample.conf
|
||||
# Measure postfix queue statistics
|
||||
# This plugin ONLY supports non-Windows
|
||||
[[inputs.postfix]]
|
||||
## Postfix queue directory. If not provided, telegraf will try to use
|
||||
## 'postconf -h queue_directory' to determine it.
|
||||
# queue_directory = "/var/spool/postfix"
|
||||
```
|
||||
|
||||
### Permissions
|
||||
|
||||
Telegraf will need read access to the files in the queue directory. You may
|
||||
need to alter the permissions of these directories to provide access to the
|
||||
telegraf user.
|
||||
|
||||
This can be setup either using standard unix permissions or with Posix ACLs,
|
||||
you will only need to use one method:
|
||||
|
||||
Unix permissions:
|
||||
|
||||
```sh
|
||||
sudo chgrp -R telegraf /var/spool/postfix/{active,hold,incoming,deferred}
|
||||
sudo chmod -R g+rXs /var/spool/postfix/{active,hold,incoming,deferred}
|
||||
sudo usermod -a -G postdrop telegraf
|
||||
sudo chmod g+r /var/spool/postfix/maildrop
|
||||
```
|
||||
|
||||
Posix ACL:
|
||||
|
||||
```sh
|
||||
sudo setfacl -Rm g:telegraf:rX /var/spool/postfix/
|
||||
sudo setfacl -dm g:telegraf:rX /var/spool/postfix/
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
- postfix_queue
|
||||
- tags:
|
||||
- queue
|
||||
- fields:
|
||||
- length (integer)
|
||||
- size (integer, bytes)
|
||||
- age (integer, seconds)
|
||||
|
||||
## Example Output
|
||||
|
||||
```text
|
||||
postfix_queue,queue=active length=3,size=12345,age=9
|
||||
postfix_queue,queue=hold length=0,size=0,age=0
|
||||
postfix_queue,queue=maildrop length=1,size=2000,age=2
|
||||
postfix_queue,queue=incoming length=1,size=1020,age=0
|
||||
postfix_queue,queue=deferred length=400,size=76543210,age=3600
|
||||
```
|
114
plugins/inputs/postfix/postfix.go
Normal file
114
plugins/inputs/postfix/postfix.go
Normal file
|
@ -0,0 +1,114 @@
|
|||
//go:generate ../../../tools/readme_config_includer/generator
|
||||
//go:build !windows
|
||||
|
||||
// postfix doesn't aim for Windows
|
||||
|
||||
package postfix
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type Postfix struct {
|
||||
QueueDirectory string `toml:"queue_directory"`
|
||||
}
|
||||
|
||||
func (*Postfix) SampleConfig() string {
|
||||
return sampleConfig
|
||||
}
|
||||
|
||||
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: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred"} {
|
||||
fields, err := qScan(filepath.Join(p.QueueDirectory, q), acc)
|
||||
if err != nil {
|
||||
acc.AddError(fmt.Errorf("error scanning queue %q: %w", q, err))
|
||||
continue
|
||||
}
|
||||
|
||||
acc.AddFields("postfix_queue", fields, map[string]string{"queue": q})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
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) (map[string]interface{}, 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 %q: %w", 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 nil, err
|
||||
}
|
||||
|
||||
var age int64
|
||||
if !oldest.IsZero() {
|
||||
age = int64(time.Since(oldest) / time.Second)
|
||||
} else if length != 0 {
|
||||
// system doesn't support ctime
|
||||
age = -1
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{"length": length, "size": size}
|
||||
if age != -1 {
|
||||
fields["age"] = age
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
inputs.Add("postfix", func() telegraf.Input {
|
||||
return &Postfix{
|
||||
QueueDirectory: "/var/spool/postfix",
|
||||
}
|
||||
})
|
||||
}
|
57
plugins/inputs/postfix/postfix_test.go
Normal file
57
plugins/inputs/postfix/postfix_test.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
//go:build !windows
|
||||
|
||||
package postfix
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
)
|
||||
|
||||
func TestGather(t *testing.T) {
|
||||
td := t.TempDir()
|
||||
|
||||
for _, q := range []string{"active", "hold", "incoming", "maildrop", "deferred/0/0", "deferred/F/F"} {
|
||||
require.NoError(t, os.MkdirAll(filepath.FromSlash(td+"/"+q), 0750))
|
||||
}
|
||||
|
||||
require.NoError(t, os.WriteFile(filepath.FromSlash(td+"/active/01"), []byte("abc"), 0640))
|
||||
require.NoError(t, os.WriteFile(filepath.FromSlash(td+"/active/02"), []byte("defg"), 0640))
|
||||
require.NoError(t, os.WriteFile(filepath.FromSlash(td+"/hold/01"), []byte("abc"), 0640))
|
||||
require.NoError(t, os.WriteFile(filepath.FromSlash(td+"/incoming/01"), []byte("abcd"), 0640))
|
||||
require.NoError(t, os.WriteFile(filepath.FromSlash(td+"/deferred/0/0/01"), []byte("abc"), 0640))
|
||||
require.NoError(t, os.WriteFile(filepath.FromSlash(td+"/deferred/F/F/F1"), []byte("abc"), 0640))
|
||||
|
||||
p := Postfix{
|
||||
QueueDirectory: td,
|
||||
}
|
||||
|
||||
var acc testutil.Accumulator
|
||||
require.NoError(t, p.Gather(&acc))
|
||||
|
||||
metrics := map[string]*testutil.Metric{}
|
||||
for _, m := range acc.Metrics {
|
||||
metrics[m.Tags["queue"]] = m
|
||||
}
|
||||
|
||||
require.Equal(t, int64(2), metrics["active"].Fields["length"])
|
||||
require.Equal(t, int64(7), metrics["active"].Fields["size"])
|
||||
require.InDelta(t, 0, metrics["active"].Fields["age"], 10)
|
||||
|
||||
require.Equal(t, int64(1), metrics["hold"].Fields["length"])
|
||||
require.Equal(t, int64(3), metrics["hold"].Fields["size"])
|
||||
|
||||
require.Equal(t, int64(1), metrics["incoming"].Fields["length"])
|
||||
require.Equal(t, int64(4), metrics["incoming"].Fields["size"])
|
||||
|
||||
require.Equal(t, int64(0), metrics["maildrop"].Fields["length"])
|
||||
require.Equal(t, int64(0), metrics["maildrop"].Fields["size"])
|
||||
require.Equal(t, int64(0), metrics["maildrop"].Fields["age"])
|
||||
|
||||
require.Equal(t, int64(2), metrics["deferred"].Fields["length"])
|
||||
require.Equal(t, int64(6), metrics["deferred"].Fields["size"])
|
||||
}
|
32
plugins/inputs/postfix/postfix_windows.go
Normal file
32
plugins/inputs/postfix/postfix_windows.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
//go:build windows
|
||||
|
||||
package postfix
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/plugins/inputs"
|
||||
)
|
||||
|
||||
//go:embed sample.conf
|
||||
var sampleConfig string
|
||||
|
||||
type Postfix struct {
|
||||
Log telegraf.Logger `toml:"-"`
|
||||
}
|
||||
|
||||
func (*Postfix) SampleConfig() string { return sampleConfig }
|
||||
|
||||
func (p *Postfix) Init() error {
|
||||
p.Log.Warn("Current platform is not supported")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*Postfix) Gather(_ telegraf.Accumulator) error { return nil }
|
||||
|
||||
func init() {
|
||||
inputs.Add("postfix", func() telegraf.Input {
|
||||
return &Postfix{}
|
||||
})
|
||||
}
|
6
plugins/inputs/postfix/sample.conf
Normal file
6
plugins/inputs/postfix/sample.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Measure postfix queue statistics
|
||||
# This plugin ONLY supports non-Windows
|
||||
[[inputs.postfix]]
|
||||
## Postfix queue directory. If not provided, telegraf will try to use
|
||||
## 'postconf -h queue_directory' to determine it.
|
||||
# queue_directory = "/var/spool/postfix"
|
16
plugins/inputs/postfix/stat_ctim.go
Normal file
16
plugins/inputs/postfix/stat_ctim.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
//go: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())
|
||||
}
|
16
plugins/inputs/postfix/stat_ctimespec.go
Normal file
16
plugins/inputs/postfix/stat_ctimespec.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
//go: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())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue