June 2017: Error log
Meetup #40. Please RSVP at Meetup.
We get started at 6:30 pm.
Sponsors
Venue provided by Startup Edmonton.
Talks
Structured logging
Adam Wolfe Gordon made the case for structured logging: we log for debugging, monitoring, and auditing, but we almost never read a log start to finish — we grep, awk, and search it — so logs should be optimized for machines rather than humans. The talk showed how to emit logs as JSON with dynamic values as key/value pairs and a constant message, contrasting a normal log.Printf line with a structured log.KV("method", ...).KV("client_addr", ...).Info("got request") call. He demoed the aybabtme/log library (a small wrapper around go-kit's log) and tools for reading the output: humanlog for humans, jq for filtering, and an ELK/Kibana stack for searching. The main caveat is that structured logging suits servers, while CLI output should stay human-oriented.
Key points:
- Logs are for debugging, monitoring, and auditing — not linear reading.
- Emit JSON with constant messages and key/value dynamic fields.
- Several libraries exist:
sirupsen/logrus,go-kit/kit/log,aybabtme/log. - Use
humanlogto render JSON logs for humans,jqto filter, ELK/Kibana to search. - Structured logging pays off on servers; keep CLI logs human-friendly.
Adam Wolfe Gordon (slides PDF, code)
Effective error handling
Gerrit Renker laid out a seven-part strategy for handling errors in Go, framed around the idea that errors are values and events rather than exceptions. He argued for logging errors where they are handled rather than where they occur, annotating them with context (for example with github.com/pkg/errors, whose %+v adds stack traces), and aggregating noisy failures with tools like go-multierror and go-errortree. The talk stressed testing behavior, using predicates such as os.IsNotExist instead of comparing error literals, and finished with concurrent error handling using errgroup, where a shared context cancels sibling goroutines when one fails. He also recommended errcheck to catch unchecked errors and Rob Pike's errWriter pattern for collecting errors internally.
Key points:
- Errors are values; the
errorinterface is justError() string. - Errors are events — handle them, don't ignore them (
errcheckhelps). - Log where errors are handled, not where they occur.
- Add context with
pkg/errors;%+vprints a stack trace. - Aggregate noisy errors with
go-multierror/go-errortree. - Test error behavior (e.g.
os.IsNotExist), not literal values. - For concurrent work, use
errgroupand cancel via context.
News
- Go 1.9 beta 2
- Go 1.9 draft release notes
- What’s new in Google’s Go 1.9 language InfoWorld
- Web Development with Go Jonathan Calhoun
- Ultimate Go Programming LiveLessons William Kennedy