Start learning free

LESSON 141 OF 173 · BACKEND: TESTS AND RUNNING IT

Logging

Practice

On a server nobody watches the screen, so System.out.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. The shop already has a logger, private static final Logger log = LoggerFactory.getLogger(ShopController.class);, and each line it writes gets a level: INFO with log.info for things that went as planned, WARN with log.warn for something unusual.

You give log.info a text with {} in it, then the values: each value goes in place of the next {}, in order. In a sign-up route, for example:

log.info("New user: {}, age {}", name, age);

With name "Ana" and age 30, the line's message is New user: Ana, age 30. The check prints each line with its level and the logger's name in front, like INFO shop.ShopController - ….

Test the log too, because a log line can break without anyone noticing. A Logback ListAppender is a list that keeps every log line it gets: start it with start() and add it to the "ROOT" logger, which gets every logger's lines. After the request, logs.list holds the lines, and each line's getFormattedMessage() is its message with every {} filled in.

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

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

Your task: log every placed order with log.info and every order for an unknown product with log.warn. Then write testOrderIsLogged, which catches the log lines in a ListAppender, posts 2 Mugs, and checks that exactly one line was logged, with the message "Order placed: 2 x Mug, total 24". 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 log.info and log.warn, and to write a test that reads the log with a ListAppender.


Hint
Put each log line right before its return, where everything it needs is known. getFormattedMessage() gives only the message, without the level or the logger's name: "Order placed: …".


STEP 1 OF 9
    Ctrl + Enter to check