Real World Example

Debugging a Failed Order in Production

A customer of a food delivery app says "my payment went through but the order failed". The support engineer searches the logs for the order id. Good log lines make this a two-minute job instead of a two-day one.

customer complaint -> order id 102 -> search logs "order 102"
     -> INFO  Order 102 created for user 57, total Rs.649
     -> INFO  Payment captured for order 102 (razorpay pay_Nx81...)
     -> ERROR Failed to reserve stock for order 102: product 9 out of stock
     -> fix: refund + alert; root cause found in minutes

ShopEase OrderService with Good Logging

package com.shopease.order;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    private final PaymentGateway paymentGateway;
    private final StockService stockService;

    public OrderService(PaymentGateway paymentGateway, StockService stockService) {
        this.paymentGateway = paymentGateway;
        this.stockService = stockService;
    }

    public void placeOrder(long orderId, long userId, int total) {
        log.info("Order {} created for user {}, total Rs.{}", orderId, userId, total);
        String paymentId = paymentGateway.charge(orderId, total);
        log.info("Payment captured for order {} ({})", orderId, paymentId);
        try {
            stockService.reserve(orderId);
        } catch (OutOfStockException e) {
            log.error("Failed to reserve stock for order {}, refunding payment {}", orderId, paymentId, e);
            paymentGateway.refund(paymentId);
            throw e;
        }
        log.debug("Order {} completed", orderId);
    }
}

Example

curl -s -X POST http://localhost:8080/api/orders/demo

Example output

10:31:02.441 INFO  [nio-8080-exec-3] c.s.o.OrderService - Order 102 created for user 57, total Rs.649
10:31:02.913 INFO  [nio-8080-exec-3] c.s.o.OrderService - Payment captured for order 102 (pay_Nx81Qa7)
10:31:02.920 ERROR [nio-8080-exec-3] c.s.o.OrderService - Failed to reserve stock for order 102, refunding payment pay_Nx81Qa7
com.shopease.order.OutOfStockException: product 9 out of stock
	at com.shopease.order.StockService.reserve(StockService.java:31)
	at com.shopease.order.OrderService.placeOrder(OrderService.java:27)
	...

Logging Rules Used in Industry

  • Log business events at INFO with ids (order id, user id), never personal data.
  • Log every caught-and-handled failure at WARN or ERROR with the exception.
  • Use DEBUG for details; keep production at INFO.
  • Use DevTools only in development; it is disabled automatically in the packaged jar.

Exercise: Write the logging line for: a WARN when a product's stock drops below 5 after an order (include product id and stock left).

Show answer
if (stockLeft < 5) {
    log.warn("Low stock for product {}: {} left", productId, stockLeft);
}