Careeroza
Real World Example
Debugging a Slow Checkout During a Big Sale
During a Flipkart Big Billion Days style sale, the ShopEase on-call engineer gets an alert: "order-service p95 latency 2.4 s". With observability in place the investigation takes minutes:
- Metrics (Grafana): latency is high only for
POST /api/orders;hikaricp_connections_pendingin payment-service is climbing. - Traces (Zipkin/Tempo): a slow trace shows 1.9 s spent in the span
payment-service SELECT payments. - Logs (Loki, filtered by the trace ID):
WARN ... query took 1874 ms: SELECT * FROM payments WHERE order_id = ?. - Root cause: a missing index on
payments.order_idafter a migration. Add the index; latency drops to 180 ms.
A Complete Observability Setup for One Service
payment-service
application.yml
spring:
application:
name: payment-service
management:
endpoints:
web:
exposure:
include: health,info,prometheus,loggers
endpoint:
health:
probes:
enabled: true # /actuator/health/liveness and /readiness for Kubernetes
metrics:
tags:
application: payment-service
distribution:
percentiles-histogram:
http.server.requests: true
tracing:
sampling:
probability: 0.1
zipkin:
tracing:
endpoint: http://zipkin.observability:9411/api/v2/spans
logging:
structured:
format:
console: ecs@Service
@RequiredArgsConstructor
@Slf4j
public class PaymentService {
private final ObservationRegistry observations;
private final MeterRegistry meters;
private final RazorpayGateway razorpay;
public PaymentResult charge(ChargePayment cmd) {
return Observation.createNotStarted("payment.charge", observations) // span + timer metric
.lowCardinalityKeyValue("method", cmd.method().name()) // UPI, CARD, NETBANKING
.observe(() -> {
PaymentResult result = razorpay.capture(cmd);
if (!result.captured()) {
meters.counter("shopease.payments.failed", "reason", result.reason()).increment();
log.warn("Payment declined for order {}: {}", cmd.orderId(), result.reason());
}
return result;
});
}
}Tip: One Observation gives you three things at once: a span in the trace, a timer metric (payment_charge_seconds) and the trace ID in log lines written inside it.