Testing and Production Development· 35 min

Observability and Error Handling

Use health checks, metrics, logs, tracing, and error tracking to operate a service.

Java interview lesson
Question 29 · Not reviewed

Production · operations

Can you explain this clearly in an interview?

Use the strong answer as your reference, explain it aloud in your own words, then choose how soon you want to review it again.

Interview prompt

Observability and Error Handling

Explain it aloud in your own words

Strong answer

Observability means you can explain a production behavior from the signals the service emits. Metrics (Micrometer) show rates, errors, and latency over time; structured logs with a correlation or trace id explain individual events; distributed tracing (OpenTelemetry or Micrometer Tracing) shows where time went across services. Error handling completes the picture: map failures to consistent ProblemDetail responses, log once at the right level with context, and alert on symptoms users feel rather than on every exception.

Key points

  • Track the RED signals per endpoint: rate, errors, and duration percentiles, not just averages.
  • Keep metric tag cardinality bounded; never tag with user ids or raw URLs.
  • Liveness checks whether the process should be restarted; readiness checks whether it should receive traffic.
  • Log an exception once where it is handled, with context, rather than at every layer that rethrows it.

Interviewer looks for

Walk through how you would investigate a latency spike or error burst using metrics, traces, and logs, and explain how your error responses stay stable for clients without leaking internals.

Java example

1@RestControllerAdvice
2class ApiErrors {
3  private static final Logger log = LoggerFactory.getLogger(ApiErrors.class);
4
5  @ExceptionHandler(OrderNotFoundException.class)
6  ProblemDetail notFound(OrderNotFoundException ex) {
7    var problem = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
8    problem.setProperty("code", "ORDER_NOT_FOUND");
9    return problem;
10  }
11
12  @ExceptionHandler(Exception.class)
13  ProblemDetail unexpected(Exception ex) {
14    log.error("unhandled_error traceId={}", MDC.get("traceId"), ex);
15    return ProblemDetail.forStatus(HttpStatus.INTERNAL_SERVER_ERROR);
16  }
17}
18
19@Service
20class CheckoutService {
21  private final Timer checkoutTimer;
22  CheckoutService(MeterRegistry registry) {
23    this.checkoutTimer = Timer.builder("checkout.duration")
24        .publishPercentiles(0.5, 0.95, 0.99)
25        .register(registry);
26  }
27  Receipt checkout(Cart cart) { return checkoutTimer.record(() -> process(cart)); }
28}

Topic interview questions

Revise this topic like an interviewer

These questions are tied to this lesson. Read each question aloud, then compare your explanation with the strong answer.

5 questions
Q1Basic

What are the three pillars of observability and what does each answer?

Strong answer

Metrics answer how much and how often over time, logs answer what happened in a specific event, and traces answer where time was spent across components for one request. They are most useful when linked through a shared trace id.

Q2Intermediate

Why are latency percentiles more useful than averages?

Strong answer

Averages hide tail behavior: a few very slow requests can be invisible in the mean while still affecting many users. p95 and p99 show the experience of the slowest requests, which is usually what SLOs and alerts should target.

Q3Intermediate

What is metric cardinality and why does it matter?

Strong answer

Cardinality is the number of unique tag combinations for a metric. Tagging with unbounded values such as user ids or full URLs creates huge numbers of time series, increasing memory and cost and sometimes taking down the metrics backend. Use bounded tags such as route templates and status classes.

Q4Intermediate

What is the difference between liveness and readiness probes?

Strong answer

Liveness tells the platform whether the process is broken and should be restarted. Readiness tells it whether the instance can currently accept traffic, for example after warm-up or while a dependency is unavailable. Putting a database check in liveness can cause needless restart loops.

Q5Advanced

How should a Spring Boot API return errors to clients?

Strong answer

Centrally with @RestControllerAdvice, using a stable shape such as RFC 9457 ProblemDetail with an HTTP status, a machine-readable code, field errors for validation, and a correlation id. Stack traces, SQL, and internal class names stay in logs, not in the response.

How well do you know this?

Your review choice is saved locally and synced to your learner profile when signed in.