From 3e27cad5b17f7285a92564c7625484a8711b8c3b Mon Sep 17 00:00:00 2001 From: Blallo Date: Fri, 3 May 2019 10:45:35 +0200 Subject: [PATCH] Allow socket activation from systemd. --- cmd/circologd/main.go | 31 ++++++++++++++++---------- cmd/circologd/sockets.go | 48 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 cmd/circologd/sockets.go diff --git a/cmd/circologd/main.go b/cmd/circologd/main.go index 31821e7..4063d8b 100644 --- a/cmd/circologd/main.go +++ b/cmd/circologd/main.go @@ -31,9 +31,10 @@ func removeAtExit(socket string) { func main() { var err error + var syslogSocket SyslogSocket var logFmt formatter.SyslogRFC logFmt.Format = syslog.Automatic - syslogSocketPath := flag.String("syslogd-socket", "", "The socket to listen to syslog addresses") + flag.Var(&syslogSocket, "syslogd-socket", "The socket to listen to syslog addresses") // dumpSocketPath := flag.String("dump-socket", "/run/buffer.sock", "The socket that user will connect to in order to receive logs") bufsize := flag.Int("buffer-size", 1000, "Number of messages to keep") syslogAddr := flag.String("syslog-addr", "127.0.0.1:9514", "Address:port where to listen for syslog messages") @@ -56,18 +57,24 @@ func main() { server.SetFormat(logFmt.Format) fmt.Printf("Syslog format set to: %s\n", logFmt.String()) server.SetHandler(handler) - if *syslogSocketPath != "" { - if err = server.ListenUnixgram(*syslogSocketPath); err != nil { - fmt.Fprintln(os.Stderr, "argh", err) - os.Exit(1) - } - defer cleanSocket(*syslogSocketPath) - fmt.Printf("Binding socket `%s` [syslog]\n", *syslogSocketPath) + if syslogSocket.isSocketActivated { + fmt.Printf("Binding to socket `%s` [syslog]\n", syslogSocket.String()) + server.Listen(syslogSocket.Listener) } else { - fmt.Printf("Binding address `%s` [syslog]\n", *syslogAddr) - if err = server.ListenUDP(*syslogAddr); err != nil { - fmt.Fprintln(os.Stderr, "argh", err) - os.Exit(1) + syslogSocketPath := syslogSocket.Path + if syslogSocketPath != "" { + if err = server.ListenUnixgram(syslogSocketPath); err != nil { + fmt.Fprintln(os.Stderr, "argh", err) + os.Exit(1) + } + fmt.Printf("Binding socket `%s` [syslog]\n", syslogSocketPath) + removeAtExit(syslogSocketPath) + } else { + fmt.Printf("Binding address `%s` [syslog]\n", *syslogAddr) + if err = server.ListenUDP(*syslogAddr); err != nil { + fmt.Fprintln(os.Stderr, "argh", err) + os.Exit(1) + } } } if err = server.Boot(); err != nil { diff --git a/cmd/circologd/sockets.go b/cmd/circologd/sockets.go new file mode 100644 index 0000000..aa2919c --- /dev/null +++ b/cmd/circologd/sockets.go @@ -0,0 +1,48 @@ +package main + +import ( + "net" + + "github.com/coreos/go-systemd/activation" +) + +// SyslogSocket is a struct eventually containing a net.Listener +// ready with messages, and a Path in case the Listener is not present. +type SyslogSocket struct { + Listener net.Listener + Path string + isSocketActivated bool +} + +func (s *SyslogSocket) Set(v string) error { + sock, err := s.getActivationSocket() + if err != nil { + return err + } + s.isSocketActivated = false + if sock != nil { + s.Listener = sock + s.isSocketActivated = true + return nil + } + s.Path = v + return nil +} + +func (s *SyslogSocket) String() string { + if s.isSocketActivated { + return "systemd-provided" + } + return s.Path +} + +func (s *SyslogSocket) getActivationSocket() (net.Listener, error) { + listeners, err := activation.Listeners() + if err != nil { + return nil, err + } + if len(listeners) == 0 { + return nil, nil + } + return listeners[0], nil +}