Careeroza
Centralized Logging
Ship Logs Off the Container
Containers are deleted and replaced all the time, and their local log files go with them. So every service writes logs to stdout, and a collector ships them to one central store:
order-service pods ─┐
payment-service pods┼─ stdout (JSON) ─> collector (Promtail / Fluent Bit / Filebeat)
gateway pods ───────┘ |
v
Loki or Elasticsearch (ELK / EFK)
|
v
Grafana / Kibana: search traceId="6650f1e2..."| Stack | Parts | Good for |
|---|---|---|
| ELK / EFK | Elasticsearch + Logstash or Fluentd + Kibana | Powerful full-text search; heavier to run |
| Grafana Loki | Loki + Promtail/Alloy + Grafana | Cheap (indexes labels only); same UI as metrics and traces |
| Cloud | AWS CloudWatch, GCP Cloud Logging, Azure Monitor | No servers to run |
Structured JSON Logs (Spring Boot 3.4+)
Plain-text logs are hard to search. Spring Boot 3.4 can write structured logs in Elastic Common Schema (ECS), Logstash or GELF format with one property. MDC values such as traceId are included as fields:
Configuration and one log line
application.yml
logging:
structured:
format:
console: ecs # or: logstash, gelf
level:
com.shopease: INFOExample output
{"@timestamp":"2026-10-14T16:12:10.118Z","log":{"level":"WARN","logger":"com.shopease.payment.PaymentService"},"process":{"pid":1,"thread":{"name":"nio-8084-exec-1"}},"service":{"name":"payment-service"},"message":"Payment declined for order 1002: insufficient funds","traceId":"6650f1e2a1b3c4d5e6f708192a3b4c5d","spanId":"0d1e2f3a4b5c6d7e","correlationId":"android-7731","ecs":{"version":"8.11"}}// Log with context, not with string concatenation of secrets
log.warn("Payment declined for order {}: {}", orderId, reason); // good
log.info("Card " + cardNumber + " charged"); // BAD: card data in logs (PCI-DSS!)Logging Rules for Microservices
- Log to stdout only; let the platform collect and rotate.
- Every line carries
service,traceIdand (optionally)correlationId. - Use levels properly:
ERROR= someone must act,WARN= unusual but handled,INFO= business events,DEBUG= off in production. - Never log passwords, JWTs, OTPs, full card numbers, Aadhaar or PAN numbers. Mask them.
- Log the business key (orderId 1001) so support staff can search without a trace ID.
Note: Change a log level at runtime without a restart: POST /actuator/loggers/com.shopease.payment with {"configuredLevel":"DEBUG"}. Protect the actuator endpoints!