# Java Observability

> Observabilidade Java/Spring: Actuator, Micrometer, Prometheus, OpenTelemetry, Logback JSON, MDC. Use para configurar health checks, métricas, traces, logs estruturados ou depurar problemas em produção Spring Boot.

- Skill: `nxs-cafi/java-observability` (Agent Skill)
- Install (CLI): `npx skillmds@latest add nxs-cafi/java-observability`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nxs-cafi/java-observability/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: nxs-cafi (https://skillmd.com/u/nxs-cafi)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/nxs-cafi/java-observability

---


# Observabilidade Java — Spring Boot

## Os Três Pilares

| Pilar | Ferramenta Spring | Pergunta |
|-------|-------------------|----------|
| Logs | Logback + Logstash encoder | O que aconteceu? |
| Métricas | Micrometer + Actuator | Quantas vezes? Quanto tempo? |
| Traces | OpenTelemetry Java Agent | Por onde passou? |

## Spring Boot Actuator

```yaml
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: when_authorized
      probes:
        enabled: true  # /health/liveness e /health/readiness para K8s
  metrics:
    export:
      prometheus:
        enabled: true
```

```java
// Health check customizado
@Component
public class PaymentProviderHealthIndicator implements HealthIndicator {
    private final PaymentClient client;

    @Override
    public Health health() {
        try {
            client.ping();
            return Health.up().withDetail("provider", "stripe").build();
        } catch (Exception e) {
            return Health.down(e).withDetail("provider", "stripe").build();
        }
    }
}
```

## Micrometer — Métricas

```java
@Service
@RequiredArgsConstructor
public class CreateOrderService {
    private final MeterRegistry registry;
    private final OrderRepository orderRepository;

    @Transactional
    public OrderResponse execute(CreateOrderCommand cmd) {
        return Timer.builder("order.create.duration")
            .description("Time to create an order")
            .tag("status", "success")
            .register(registry)
            .record(() -> {
                var order = Order.create(cmd.customerId(), cmd.items());
                orderRepository.save(order);
                registry.counter("order.created", "currency", order.currency().name()).increment();
                return OrderResponse.from(order);
            });
    }
}
```

**Métricas obrigatórias em produção:**
- `http.server.requests` (latência por endpoint)
- Métricas de negócio: `order.created`, `payment.failed`
- JVM: heap, GC (via Actuator/Prometheus)

## Logging Estruturado (Logback JSON)

```xml
<!-- logback-spring.xml -->
<configuration>
  <appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
      <includeMdcKeyName>trace_id</includeMdcKeyName>
      <includeMdcKeyName>request_id</includeMdcKeyName>
      <includeMdcKeyName>user_id</includeMdcKeyName>
    </encoder>
  </appender>
  <root level="INFO"><appender-ref ref="JSON"/></root>
</configuration>
```

```java
// Filtro MDC para contexto de requisição
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestContextFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
            throws ServletException, IOException {
        var requestId = Optional.ofNullable(req.getHeader("X-Request-ID"))
            .orElse(UUID.randomUUID().toString());
        MDC.put("request_id", requestId);
        MDC.put("trace_id", Optional.ofNullable(req.getHeader("traceparent"))
            .orElse(requestId));
        try {
            chain.doFilter(req, res);
            res.setHeader("X-Request-ID", requestId);
        } finally {
            MDC.clear();
        }
    }
}

// Uso
@Slf4j
@Service
public class CreateOrderService {
    public OrderResponse execute(CreateOrderCommand cmd) {
        log.info("order_created customer_id={} items_count={}",
            cmd.customerId(), cmd.items().size());
        // ...
    }
}
```

## OpenTelemetry

```yaml
# application.yml com Java Agent
# java -javaagent:opentelemetry-javaagent.jar -jar app.jar
management:
  otlp:
    tracing:
      endpoint: http://otel-collector:4318/v1/traces
  tracing:
    sampling:
      probability: 1.0  # reduzir em prod (ex: 0.1)
```

```java
// Span customizado
@Service
@RequiredArgsConstructor
public class CreateOrderService {
    private final Tracer tracer;

    public OrderResponse execute(CreateOrderCommand cmd) {
        var span = tracer.spanBuilder("create_order")
            .setAttribute("order.customer_id", cmd.customerId().toString())
            .startSpan();
        try (var scope = span.makeCurrent()) {
            // lógica
            span.setStatus(StatusCode.OK);
            return result;
        } catch (Exception e) {
            span.recordException(e);
            span.setStatus(StatusCode.ERROR, e.getMessage());
            throw e;
        } finally {
            span.end();
        }
    }
}
```

## Convenções de Log

| Evento | Nível | Campos obrigatórios |
|--------|-------|---------------------|
| Request recebido | DEBUG | request_id, method, path |
| Operação de negócio | INFO | event_name, entity_id |
| Erro de negócio | WARN | event_name, reason, entity_id |
| Erro inesperado | ERROR | event_name, stack trace |
| Sistema crítico | ERROR/CRITICAL | component |

## O que NUNCA Logar

```java
// ❌ PII
log.info("User login email={}", user.getEmail());
log.info("Payment card={}", cardNumber);

// ✅ IDs opacos
log.info("user_login user_id={}", user.getId());
log.info("payment_processed payment_id={}", payment.getId());
```

## Stack Recomendada

```
Coleta    → OpenTelemetry Collector
Logs      → Loki / CloudWatch / Datadog
Métricas  → Prometheus + Grafana (via Actuator /actuator/prometheus)
Traces    → Jaeger / Tempo
Alertas   → Alertmanager / PagerDuty
```

## Equivalência Python (SKILL_5)

| Python | Java |
|--------|------|
| structlog | Logback + LogstashEncoder |
| prometheus_client | Micrometer |
| opentelemetry-sdk | OTEL Java Agent |
| FastAPI middleware | Servlet Filter + MDC |

