Stage 1 · Code
Standard Library Toolkit
Log for Search, Not Just for Reading
A log line that sounds nice to a human can still be awkward for machines to search. `log/slog` helps you produce logs as structured facts instead of loose sentences.
Why Structured Logs Help
Suppose a payment request fails in production. A plain log line like 'payment failed for user 42 in 381ms on node-a' is readable, but the important facts are trapped inside one sentence. A machine has to scrape the sentence back apart before it can filter by user, duration, or node.
Structured logs keep the sentence and the facts separate. You still write a short message, but you also attach key-value fields such as user_id=42, duration_ms=381, and node=node-a. Now humans can read the line and machines can query it cleanly.
| Style | Example | Operational downside |
|---|---|---|
| Plain string only | payment failed for user 42 in 381ms on node-a | Important values are embedded in prose |
| Structured log | msg=payment failed user_id=42 duration_ms=381 node=node-a | Slightly more deliberate to write, but far easier to filter and aggregate |
When something breaks, logs become part of the investigation record. The more cleanly your data is shaped, the faster you can answer questions like 'show me every failed payment on node-a in the last 5 minutes.'
Building a `slog` Logger
Go's standard structured logging package is log/slog. You create a logger by choosing a handler, then writing logs through that logger. The handler decides how the logs are rendered.
{
"time": "2026-07-20T09:15:30.000Z",
"level": "INFO",
"msg": "cache warmed",
"items": 18,
"region": "ap-south-1"
}Exact field order can vary, but the shape is stable: one event, one message, and a set of named fields that downstream tools can index.
Levels and Fields
A structured logger is more than a prettier Println. It gives you levels and reusable context. Levels let you separate normal operational information from warnings and actual failures. Reusable context lets you attach the same fields to a whole family of logs without rewriting them every time.
Debugis for detail you usually want during development or deeper investigation.Infois for normal, meaningful events in the program's life.Warnis for situations that look unhealthy but have not fully failed.Erroris for failures your code could not complete successfully.
Standard Library Versus Third-Party Loggers
You will also see popular third-party logging libraries in real Go codebases. That is normal. Some teams adopt them for ecosystem conventions, special handlers, performance tuning, or a style they already use across many services.
The standard library tradeoff is straightforward: log/slog gives you a solid, built-in baseline with no extra dependency decisions. A third-party logger may offer features or integration helpers your team wants, but every extra dependency is also a long-term choice to learn, upgrade, and keep consistent. Neither choice is automatically right in every project.
The message should summarize the event. The fields should carry the search-worthy details. If the only copy of a request ID lives inside the English sentence, you gave up much of the benefit of structured logging.
Quiz
Why are structured logs often more useful in production than plain string logs?
Practice
Write a function `RequestLogFields(traceID string, statusCode int, durationMs int) []any` that returns key-value pairs in this exact order: `trace_id`, traceID, `status_code`, statusCode, `duration_ms`, durationMs.
Summary
- Structured logs separate the human message from the machine-searchable facts.
log/slogbuilds loggers around handlers such as text and JSON output.- Log levels help you express severity and intent.
- Shared fields added with
.With(...)keep repeated context consistent. - The standard library offers a strong default, while third-party loggers add features at the cost of another dependency choice.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.