Search code examples
servicegosyslog

Why is Go's Logger not closing connections to syslog?


I’m having trouble with a service i’m writing. I have it logging to syslog like this: http://technosophos.com/2013/09/14/using-gos-built-logger-log-syslog.html

but when i kill the service via CTRL-C something is leaving connections open to syslogd. I can’t see anyway to initiate a cleanup. What am I missing

e.g. syslog.Writer.Close() seems inaccessible to me but i can say the cleanup isn’t happening. I’m seeing connections stuck in a CLOSE_WAIT state and my syslogd starts bogging down and becoming uncooperative.

example:

package main

import (
    "github.com/davecgh/go-spew/spew" // DEBUG
    "log"
    "log/syslog"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    logWriter, err := syslog.New(syslog.LOG_NOTICE, "mybrokenprog")
    spew.Dump(logWriter) // DEBUG
    spew.Dump(err)       // DEBUG
    if err == nil {
        log.SetOutput(logWriter)
    }

    chansigs := make(chan os.Signal, 1)
    signal.Notify(chansigs, os.Interrupt, syscall.SIGTERM, syscall.SIGKILL)
    log.Print("writing to syslog. waiting for shutdown signal")
    for {
        sig := <-chansigs // we just wait here for a signal to shutdown
        log.Print("signal received...shutting down")
        logWriter.Close() // but this throws the panic excerpted below
        if sig == os.Interrupt {
            os.Exit(0)
        }
        os.Exit(1)
    }
}

EDIT: the above code fixes the problem. see the comments. Rebooting to clear the stuck connections to syslog fixed the problem. Once they're there, they're persistent. Even OS X's instructions for retarting syslogd did not help. EDIT: this was the error: panic: runtime error: invalid memory address or nil pointer dereference [signal 0xb code=0x1 addr=0x0 pc=0xcb4fe]

goroutine 1 [running]: log/syslog.(*Writer).Close(0x0, 0x0, 0x0) /usr/local/Cellar/go/1.5.1/libexec/src/log/syslog/syslog.go:177 +0x10e main.main(0x3)

I've no doubt I'm doing it wrong. Just a newb who doesn't yet see where.


Solution

  • The problem was with the way the program was originally structured. The main() thread was exiting before the logging goroutine and thus orphaning connections. After refactoring to prevent that, the problem went away.