Start learning free

LESSON 141 OF 173 · BACKEND: TESTS AND RUNNING IT

Logging in Go

Practice

On a server nobody watches the screen, so fmt.Println is no help there. Instead the shop writes a log: lines that are kept, so you can read them later, for example when a customer says their order went wrong. Go's log/slog package writes those lines, and each one gets a level: INFO with slog.Info for things that went as planned, WARN with slog.Warn for something unusual.

You give slog.Info a message, then pairs: a key, its value, the next key, its value. Each pair is written as key=value. In a sign-up route, for example:

slog.Info("New user", "name", name, "age", age)

With name "Ana" and age 30, the log gets the line INFO New user name=Ana age=30: the level, the message and the pairs. By default the log package also puts the date and time at the start of each line.

Test the log too, because a log line can break without anyone noticing. slog's lines go out through the log package, so a test can collect them: log.SetOutput(&logs) sends them into a strings.Builder named logs, and log.SetFlags(0) drops the date and time. Then logs.String() is exactly the lines, each ending in \n. Collecting the lines checks nothing by itself: compare them with s.Equal.

The check places three orders and shows what your shop logged for each:

POST /orders {"product_id": 1, "quantity": 2}  →  201
  log: INFO Order placed quantity=2 product=Mug total=24
POST /orders {"product_id": 6, "quantity": 3}  →  201
  log: INFO Order placed quantity=3 product=Teapot total=66
POST /orders {"product_id": 99, "quantity": 1}  →  404
  log: WARN Order for unknown product product_id=99

Your task: log every placed order with slog.Info and every order for an unknown product with slog.Warn. Then write the method TestOrderIsLogged, which collects the log lines in logs, posts 2 Mugs, and checks that logs.String() is exactly the expected line. The check runs it on the shop, where it must pass, and on two broken copies, one that logs nothing and one that logs the price instead of the total, where it must fail.


Assignment
Follow the Coding Tutorial to log the orders with slog.Info and slog.Warn, and to write a test that reads the log with log.SetOutput.


Hint
Put each log line right before its answer, where everything it needs is known. With log.SetFlags(0), each line is the level, the message and the key=value pairs, separated by spaces, with \n at the end: "INFO Order placed …\n".


STEP 1 OF 9
    Ctrl + Enter to check

    Log Basics in Go

    Keep going with Go1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free