Using Go's Built-in Logger to Log to Syslog

Sep 14 2013

The Go language has a built-in logging system, as well as a built-in syslog interface. It is convenient to be able to call Go's log.Print() from anywhere in your code and know that the message will make it's way somewhere useful. But Go's basic logging mechanism simply logs to STDOUT.

However, it is easy to redirect the log messages from STDOUT to your syslog. Here's how.

First, as early in your program as possible, you want to set the global logger to use the Syslog:

package main

import(
    "log"
    "log/syslog"
)

func main() {

    // Configure logger to write to the syslog. You could do this in init(), too.
    logwriter, e := syslog.New(syslog.LOG_NOTICE, "myprog")
    if e == nil {
        log.SetOutput(logwriter)
    }

    // Now from anywhere else in your program, you can use this:
    log.Print("Hello Logs!")
}

Now the message Hello Logs! should be sent to your system's sylog facility using the NOTICE log level, and logged as coming from myprog. Here's what the message looks like on my Mac's /var/log/system.log:

Sep 14 15:40:05 Matts-MacBook-Pro 2013-09-14T15: 40:05-06:00 Matts-MacBook-Pro.local myprog[5250]: 2013/09/14 15:40:05 Hello Logs!

Of course, the disadvantage to this approach is that you can't split your logs out by standard priorities (e.g. separating NOTICE from INFO, WARN, or DEBUG). To do that, you will need to directly use the syslog.Writer. But the advantage is that libraries can log with simple log.Print calls, and your app can redirect those messages to wherever you want -- like syslog.

And Wait! There's More!

The call to log.SetOutput() takes any io.Writer. So if you want to log to a file, open the file and pass it in! If you want to write to some other source, you simply need to implement an io.Writer. You can even just use a bytes.Buffer as a logging destination and log into memory... wait, that might not be a good idea. <!--break-->