Week 13

Observability introduction

Logging in Spring Boot

Structured Logging

Shipping Logs to the Cloud

Debugging with Logs

Health & Metrics

Appendix: Alerting (optional)

Practice

Assignment

Backend Track

Content

Let’s get practical

These exercises are for self-study β€” nothing to submit. Each one trains a skill you will need in this week's assignment. Do them in order; they take a few minutes to half an hour each.

Exercise 1 β€” From println to logger

A teammate wrote this service. It works, but its "logging" is useless in production. Rewrite it using SLF4J: proper logger, placeholders instead of +, a sensible level for each message, and the exception logged correctly.

@Service
public class ImportService {

    public int importUsers(String filename) {
        System.out.println("starting import " + filename);
        List<String> rows = readRows(filename);
        int skipped = 0;
        for (String row : rows) {
            if (row.isBlank()) {
                skipped++;
                System.out.println("ERROR!!! bad row");
                continue;
            }
            saveUser(row);
        }
        try {
            archiveFile(filename);
        } catch (IOException e) {
            System.out.println("could not archive: " + e);
        }
        System.out.println("done. skipped " + skipped);
        return rows.size() - skipped;
    }
}

πŸ’¬ Before you look at the solution: is a blank row really an ERROR? And what information is lost by "could not archive: " + e?

Exercise 2 β€” Privacy sweep

This fragment of a log file is about to be shipped to a cloud tool. Find every line that violates the "never log" rules from the Logging chapter, explain what is wrong, and write the corrected log statement for each.

1  INFO  AuthService    - Login successful for [email protected] with password Tulip2026!
2  INFO  TaskService    - Task 88 created by user 7
3  DEBUG AuthService    - Issued session token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI3In0.Sfl
4  WARN  PaymentService - Card declined for customer Ahmed El-Sayed, card number 4556 7375 8689 9855
5  INFO  TaskService    - Task 89 created by user 12

Exercise 3 β€” First line in the cloud

Using the Shipping Logs to the Cloud chapter as your recipe, get your own project's logs flowing from your laptop into your Grafana Cloud stack. Then prove you can find a needle:

  1. Add a log line with an unmistakable message, e.g. log.info("Observability practice: the eagle has landed"); behind any endpoint.
  2. Hit the endpoint a few times.
  3. In Grafana Explore, find those exact lines twice: once using only label filters, once using line contains with the word eagle.
  4. Click a line open and check its labels β€” is env saying dev?

No solution here β€” the green lines in Explore are the solution. If nothing arrives, work through the troubleshooting callout in the shipping chapter before asking for help.

Exercise 4 β€” Log mystery

A food-ordering API misbehaved this morning. A user reports: "I placed an order around 09:15 and never got a confirmation email β€” but I was charged!" Below is everything the logs show for that period. What is the root cause, which line proves it, and β€” detective bonus β€” why did the user still get charged?

09:14:58 INFO  c.h.food.OrderController   - POST /api/orders received
09:14:58 INFO  c.h.food.OrderService      - Order 501 created for user 33, total=23.90
09:14:59 INFO  c.h.food.PaymentService    - Payment captured for order 501
09:14:59 ERROR c.h.food.EmailService      - Failed to send confirmation for order 501
jakarta.mail.AuthenticationFailedException: 535 5.7.8 Authentication credentials invalid
    at com.hackyourfuture.food.EmailService.sendConfirmation(EmailService.java:44)
    at com.hackyourfuture.food.OrderService.completeOrder(OrderService.java:58)
09:15:31 INFO  c.h.food.OrderController   - POST /api/orders received
09:15:31 INFO  c.h.food.OrderService      - Order 502 created for user 9, total=11.50
09:15:32 INFO  c.h.food.PaymentService    - Payment captured for order 502
09:15:32 ERROR c.h.food.EmailService      - Failed to send confirmation for order 502
jakarta.mail.AuthenticationFailedException: 535 5.7.8 Authentication credentials invalid
    at com.hackyourfuture.food.EmailService.sendConfirmation(EmailService.java:44)

Use the full loop from the Debugging with Logs chapter: form a hypothesis (feel free to paste the trace into your AI assistant), then point to the evidence that confirms it.

Bonus β€” Watch a health check tell the truth

If you finished the Health & Metrics chapter: run your app locally with Docker Compose, open /actuator/health, stop the database container, refresh, and watch UP become DOWN. Bring it back up. Ten seconds of practice β€” permanent intuition for what your platform's health checks are doing to your service all day.


The HackYourFuture curriculum is licensed underΒ CC BY-NC-SA 4.0 *https://hackyourfuture.net/*

CC BY-NC-SA 4.0 Icons

Built with ❀️ by the HackYourFuture community · Thank you, contributors

Found a mistake or have a suggestion? Let us know in the feedback form.