Logging Go Unikernels to PaperTrail

Today we'll show you how to setup logging for your unikernels. Logging is a pretty important aspect for any web application and it's something that is used to debug problems without having to ssh into a host and tail the log files yourself. Now you might consider yourself an awk/grep/sed/cut ninja but if you're at any significant scale there's a good chance your company or organization is already using a centralized logging solution. There's literally hundreds of software applications out there that do logging ranging from the free to the obscenely expensive.

Today we'll show you how to utilize the syslog package in Go to log to PaperTrail.

First you'll want to go signup for a free account at https://papertrailapp.com/signup?plan=free.

It's a fairly simple standard form - go ahead and fill it out:


Now let's create a log destination. This effectively creates a remote syslog for us.


Go ahead and grab that host and port pair - it'll look something like this:

logsN.papertrailapp.com:XXXXX

Now let's put this into our Go file:

package main

import (
        "fmt"
        "log"
        "log/syslog"
        "time"
)

func main() {
        w, err := syslog.Dial("udp", "logsN.papertrailapp.com:XXXXX", syslog.LOG_EMERG|syslog.LOG_KERN, "myapp")
        if err != nil {
                log.Fatal("failed to dial syslog")
        }

        fmt.Println("lets send some logs")

        w.Info("Logging from a unikernel")
        w.Err("Another unikernel log message")
        w.Info("Info logging from inside unikernels")
        w.Info("Even More logging from unikernels - I thought this didn't work!?")

        time.Sleep(3 * time.Second)

        fmt.Println("exiting")
}

As you can see it sets up syslog to point to PaperTrail, shoots a few messages out and then waits a few seconds before exiting - we do this just to ensure that our messages are being delivered since we are using UDP and I also think there's a small wait after creating a new log destination.

Now if you are on a mac we'll specify Linux as the GOOS as OPS utilizeѕ ELF files but if you're on linux already than there is no need.

➜  paper GOOS=linux go build main.go
Now let's run it!
➜  paper ops run paper
Finding dependent shared libs
booting /Users/eyberg/.ops/images/paper.img ...
assigned: 10.0.2.15
lets send some logs
exiting
exit_group
exit status 1

Now you might have to wait a few seconds for these to show up in papertrail but eventually you should see something like this:


Hooray! It worked but want to see something cool?

➜  paper  ls -lh ~/.ops/images/paper.img
-rw-r--r--  1 eyberg  staff   5.4M Mar 12 11:34
/Users/eyberg/.ops/images/paper.img
➜  paper  ls -lh
total 5672
-rw-r--r--  1 eyberg  staff   533B Mar 12 11:34 bob.go
-rwxr-xr-x  1 eyberg  staff   2.8M Mar 12 11:34 paper

Turns out our original Go binary was 2.8mb while the actual resulting disk image was weighing in at a whopping 5.4mb. How's that for small? Also - next time someone asks you how you get your logs from unikernels point them at this article.

Deploy Your First Open Source Unikernel In Seconds

Get Started Now.