diff --git a/plugins/inputs/dovecot/README.md b/plugins/inputs/dovecot/README.md index 3b6129488dae3..9e44d99edbc07 100644 --- a/plugins/inputs/dovecot/README.md +++ b/plugins/inputs/dovecot/README.md @@ -14,6 +14,9 @@ the [upgrading steps][upgrading]. ## specify dovecot servers via an address:port list ## e.g. ## 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. servers = ["localhost:24242"] diff --git a/plugins/inputs/dovecot/dovecot.go b/plugins/inputs/dovecot/dovecot.go index 94c941655ccc8..ab5067534dea0 100644 --- a/plugins/inputs/dovecot/dovecot.go +++ b/plugins/inputs/dovecot/dovecot.go @@ -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 { - _, _, err := net.SplitHostPort(addr) - if err != nil { - return fmt.Errorf("%q on url %s", err.Error(), addr) + var proto string + + 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 { 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) } - host, _, _ := net.SplitHostPort(addr) + var host string + if strings.HasPrefix(addr, "/") { + host = addr + } else { + host, _, _ = net.SplitHostPort(addr) + } return gatherStats(&buf, acc, host, qtype) } diff --git a/plugins/inputs/dovecot/dovecot_test.go b/plugins/inputs/dovecot/dovecot_test.go index 97c1d2f88d964..f9ce76de947d6 100644 --- a/plugins/inputs/dovecot/dovecot_test.go +++ b/plugins/inputs/dovecot/dovecot_test.go @@ -1,7 +1,12 @@ package dovecot import ( + "bufio" "bytes" + "io" + "net" + "net/textproto" + "os" "testing" "time" @@ -42,11 +47,49 @@ func TestDovecotIntegration(t *testing.T) { 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 - tags := map[string]string{"server": "dovecot.test", "type": "global"} + tags = map[string]string{"server": "dovecot.test", "type": "global"} buf := bytes.NewBufferString(sampleGlobal) - err := gatherStats(buf, &acc, "dovecot.test", "global") + err = gatherStats(buf, &acc, "dovecot.test", "global") require.NoError(t, err) acc.AssertContainsTaggedFields(t, "dovecot", fields, tags)