We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Syslog

Long before cloud logging services (and before "cloud" was even a term), we had syslog. It was developed in the 1980s and is still widely used.

Originally, syslog was both a log-ingestion program and a protocol. We mostly care about the protocol, now implemented by many servers (rsyslog is a popular one) and clients (including the Go library).

A syslog server accepts logs from the network or a Unix socket, and then writes them to a file.

That alone can be useful if you want logs written to a different server than the one generating them. But syslog can do much more.

A syslog server can filter logs (for example, write only ERROR logs to one file), transform formats (for example, to JSON), and forward logs to other systems like databases. You can think of syslog as a "log router".

Using Syslog in Go

Since version 1, Go has shipped with log/syslog, but it does not do everything you'd expect from a package named "syslog". Its capabilities are limited, and it gets little attention these days. Notably, it does not support structured logging:

func (w *Writer) Err(m string) error

Notice the conspicuous lack of key/value pairs!

I use the github.com/samber/slog-syslog package, developed by Samuel Berthe. It provides a log/slog handler that targets syslog.

Add Syslog to Slog

Configuring github.com/samber/slog-syslog is straightforward:

  1. Open a connection to your syslog service (typically over a network or Unix socket)
  2. Configure the slog handler to send logs there!
syslogWriter, err := net.Dial("udp", "localhost:514")
if err != nil {
	panic(err)
}
syslogOptions := &slogsyslog.Option{
	Level:  slog.LevelInfo,
	Writer: syslogWriter,
}
handler := syslogOptions.NewSyslogHandler()

logger := slog.New(handler)

logger.Error("Oh noes!", "syslog", true)

We won't use syslog in Linko, but it's good to know that it exists.