plugins/inputs/dovecot: Add support for unix domain sockets (#9223)
It's safer for dovecot to export metrics via a UDS instead of tcp port, this will add support for that option. ### Required for all PRs: <!-- Complete the tasks in the following list. Change [ ] to [x] to show completion. --> - [x] Updated associated README.md. - [x] Wrote appropriate unit tests. resolves #9215 dovecot: Add support for unix domain sockets as well
This commit is contained in:
parent
175cd16f19
commit
537bc9d21d
|
|
@ -14,6 +14,9 @@ the [upgrading steps][upgrading].
|
||||||
## specify dovecot servers via an address:port list
|
## specify dovecot servers via an address:port list
|
||||||
## e.g.
|
## e.g.
|
||||||
## localhost:24242
|
## localhost:24242
|
||||||
|
## or as an UDS socket
|
||||||
|
## e.g.
|
||||||
|
## /var/run/dovecot/old-stats
|
||||||
##
|
##
|
||||||
## If no servers are specified, then localhost is used as the host.
|
## If no servers are specified, then localhost is used as the host.
|
||||||
servers = ["localhost:24242"]
|
servers = ["localhost:24242"]
|
||||||
|
|
|
||||||
|
|
@ -78,12 +78,20 @@ func (d *Dovecot) Gather(acc telegraf.Accumulator) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dovecot) gatherServer(addr string, acc telegraf.Accumulator, qtype string, filter string) error {
|
func (d *Dovecot) gatherServer(addr string, acc telegraf.Accumulator, qtype string, filter string) error {
|
||||||
_, _, err := net.SplitHostPort(addr)
|
var proto string
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%q on url %s", err.Error(), addr)
|
if strings.HasPrefix(addr, "/") {
|
||||||
|
proto = "unix"
|
||||||
|
} else {
|
||||||
|
proto = "tcp"
|
||||||
|
|
||||||
|
_, _, err := net.SplitHostPort(addr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%q on url %s", err.Error(), addr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := net.DialTimeout("tcp", addr, defaultTimeout)
|
c, err := net.DialTimeout(proto, addr, defaultTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("enable to connect to dovecot server '%s': %s", addr, err)
|
return fmt.Errorf("enable to connect to dovecot server '%s': %s", addr, err)
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +116,12 @@ func (d *Dovecot) gatherServer(addr string, acc telegraf.Accumulator, qtype stri
|
||||||
return fmt.Errorf("copying message failed for dovecot server '%s': %s", addr, err)
|
return fmt.Errorf("copying message failed for dovecot server '%s': %s", addr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
host, _, _ := net.SplitHostPort(addr)
|
var host string
|
||||||
|
if strings.HasPrefix(addr, "/") {
|
||||||
|
host = addr
|
||||||
|
} else {
|
||||||
|
host, _, _ = net.SplitHostPort(addr)
|
||||||
|
}
|
||||||
|
|
||||||
return gatherStats(&buf, acc, host, qtype)
|
return gatherStats(&buf, acc, host, qtype)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
package dovecot
|
package dovecot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/textproto"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -42,11 +47,49 @@ func TestDovecotIntegration(t *testing.T) {
|
||||||
|
|
||||||
var acc testutil.Accumulator
|
var acc testutil.Accumulator
|
||||||
|
|
||||||
|
// Test type=global server=unix
|
||||||
|
addr := "/tmp/socket"
|
||||||
|
wait := make(chan int)
|
||||||
|
go func() {
|
||||||
|
defer close(wait)
|
||||||
|
|
||||||
|
la, err := net.ResolveUnixAddr("unix", addr)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
l, err := net.ListenUnix("unix", la)
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer l.Close()
|
||||||
|
defer os.Remove(addr)
|
||||||
|
|
||||||
|
wait <- 0
|
||||||
|
conn, err := l.Accept()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
readertp := textproto.NewReader(bufio.NewReader(conn))
|
||||||
|
_, err = readertp.ReadLine()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
buf := bytes.NewBufferString(sampleGlobal)
|
||||||
|
_, err = io.Copy(conn, buf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Wait for server to start
|
||||||
|
<-wait
|
||||||
|
|
||||||
|
d := &Dovecot{Servers: []string{addr}, Type: "global"}
|
||||||
|
err := d.Gather(&acc)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tags := map[string]string{"server": addr, "type": "global"}
|
||||||
|
acc.AssertContainsTaggedFields(t, "dovecot", fields, tags)
|
||||||
|
|
||||||
// Test type=global
|
// Test type=global
|
||||||
tags := map[string]string{"server": "dovecot.test", "type": "global"}
|
tags = map[string]string{"server": "dovecot.test", "type": "global"}
|
||||||
buf := bytes.NewBufferString(sampleGlobal)
|
buf := bytes.NewBufferString(sampleGlobal)
|
||||||
|
|
||||||
err := gatherStats(buf, &acc, "dovecot.test", "global")
|
err = gatherStats(buf, &acc, "dovecot.test", "global")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
acc.AssertContainsTaggedFields(t, "dovecot", fields, tags)
|
acc.AssertContainsTaggedFields(t, "dovecot", fields, tags)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue