Pular para o conteúdo principal

Observability API

O Sagaweaw expõe uma API REST completa para monitorar sagas, consultar métricas e gerenciar dead letters. Todos os endpoints exigem autenticação por token.


Segurança

Por padrão, todos os endpoints retornam 403 se o token não estiver configurado.

Configuração

sagaweaw:
observability:
enabled: true
token: ${SAGAWEAW_TOKEN} # obrigatório

Para desabilitar completamente a API:

sagaweaw:
observability:
enabled: false

Autenticação

Passe o token em qualquer um dos dois formatos:

# Bearer token (padrão)
Authorization: Bearer <token>

# Header alternativo
X-Sagaweaw-Token: <token>

Endpoints de Sagas

GET /api/sagas

Lista sagas com paginação e filtros opcionais.

Query params:

ParâmetroTipoPadrãoDescrição
pageint0Página (0-indexed)
sizeint50Itens por página
statusstringFiltrar por status (FAILED, COMPLETED, etc.)
namestringBusca por nome da saga (contains, case-insensitive)
idstringBusca por prefixo de ID da saga
idempotencyKeystringBusca exata por chave de idempotência
fromISO 8601Data inicial (2024-01-01T00:00:00Z)
toISO 8601Data final

Exemplos:

# Últimas 50 sagas
curl -H "Authorization: Bearer $TOKEN" /api/sagas

# Sagas que falharam hoje
curl -H "Authorization: Bearer $TOKEN" \
"/api/sagas?status=FAILED&from=2024-01-15T00:00:00Z"

# Buscar por nome (contains)
curl -H "Authorization: Bearer $TOKEN" \
"/api/sagas?name=pix"

# Buscar por prefixo de ID
curl -H "Authorization: Bearer $TOKEN" \
"/api/sagas?id=01934abc"

# Buscar por idempotency key
curl -H "Authorization: Bearer $TOKEN" \
"/api/sagas?idempotencyKey=order-abc-123"

# Paginação
curl -H "Authorization: Bearer $TOKEN" \
"/api/sagas?page=2&size=25"

Resposta — array de SagaInstance:

[
{
"id": "01934...",
"name": "pix-payment",
"status": { "type": "COMPLETED", "completedAt": "2024-01-15T10:05:00Z", "durationMs": 312 },
"contextJson": "{\"transactionId\":\"...\"}",
"steps": [
{
"name": "validate-dict",
"order": 0,
"status": { "type": "COMPLETED" },
"attempt": 1,
"maxAttempts": 3,
"durationMs": 45,
"executedAt": "2024-01-15T10:04:59Z",
"completedAt": "2024-01-15T10:05:00Z"
}
],
"createdAt": "2024-01-15T10:04:58Z",
"updatedAt": "2024-01-15T10:05:00Z",
"version": 4
}
]

GET /api/sagas/{id}

Retorna uma saga específica pelo ID.

curl -H "Authorization: Bearer $TOKEN" /api/sagas/01934abc-...
  • 200 — saga encontrada
  • 404 — saga não existe

GET /api/sagas/{id}/events

Retorna o log de auditoria imutável da saga — todas as transições de estado em ordem cronológica.

curl -H "Authorization: Bearer $TOKEN" /api/sagas/01934abc-.../events

Resposta:

[
{
"id": "...",
"sagaId": "01934abc-...",
"stepName": null,
"eventType": "SAGA_STARTED",
"payload": null,
"createdAt": "2024-01-15T10:04:58Z"
},
{
"id": "...",
"sagaId": "01934abc-...",
"stepName": "validate-dict",
"eventType": "STEP_COMPLETED",
"payload": "{\"durationMs\":45}",
"createdAt": "2024-01-15T10:05:00Z"
}
]
  • 200 — lista de eventos (pode ser vazia)
  • 404 — saga não existe

POST /api/sagas/{id}/reprocess

Reexecuta uma saga a partir do step que falhou.

curl -X POST -H "Authorization: Bearer $TOKEN" /api/sagas/01934abc-.../reprocess
  • 202 — reprocessamento iniciado
  • 404 — saga não existe

Endpoints de Métricas

GET /api/sagas/metrics

Retorna métricas agregadas de todas as sagas.

curl -H "Authorization: Bearer $TOKEN" /api/sagas/metrics

Resposta:

{
"total": 1520,
"started": 3,
"executing": 12,
"completed": 1480,
"compensated": 18,
"failed": 7,
"deadLetters": 2,
"successRate": 98.7,
"byName": [
{
"name": "pix-payment",
"total": 900,
"completed": 885,
"failed": 5
}
]
}
CampoDescrição
successRatecompleted / (completed + failed + compensated) * 100, arredondado em 1 decimal
deadLettersDead letters pendentes (não reprocessadas)
byNameBreakdown por nome de saga, ordenado por volume

GET /api/sagas/stats/by-name

Retorna estatísticas por tipo de saga, incluindo duração média.

curl -H "Authorization: Bearer $TOKEN" /api/sagas/stats/by-name

Resposta:

[
{
"name": "pix-payment",
"total": 900,
"completed": 885,
"failed": 5,
"avgDurationMs": 312
},
{
"name": "order-processing",
"total": 620,
"completed": 595,
"failed": 2,
"avgDurationMs": 1840
}
]
CampoDescrição
avgDurationMsDuração média em milissegundos (apenas sagas COMPLETED)

GET /api/sagas/steps/stats

Retorna estatísticas por step, agrupadas por nome de saga. Usado pelo dashboard para identificar gargalos.

curl -H "Authorization: Bearer $TOKEN" /api/sagas/steps/stats

Resposta:

[
{
"stepName": "transmit-to-bacen",
"sagaName": "pix-payment",
"avgDurationMs": 245,
"total": 900,
"failed": 12
},
{
"stepName": "validate-dict",
"sagaName": "pix-payment",
"avgDurationMs": 18,
"total": 900,
"failed": 0
}
]

Ordenado por avgDurationMs decrescente. avgDurationMs pode ser null se nenhum step ainda terminou.

Proporção de tempo

O dashboard usa este endpoint para calcular a proporção de tempo de cada step relativa ao total da saga. Um step consumindo >40% do tempo total da saga aparece em vermelho — independente do valor absoluto em ms.


Endpoints de Dead Letters

Dead letters são steps que esgotaram todas as tentativas de retry e precisam de intervenção manual. A API expõe apenas as pendentes — itens reprocessados saem da fila e seu histórico fica no log de eventos da saga.

GET /api/dead-letters

Lista dead letters pendentes.

curl -H "Authorization: Bearer $TOKEN" /api/dead-letters

Resposta:

[
{
"id": "...",
"sagaId": "01934abc-...",
"sagaName": "pix-payment",
"stepName": "transmit-to-bacen",
"errorMessage": "Connection timeout after 3 attempts",
"errorTrace": "java.net.SocketTimeoutException: ...",
"contextSnapshot": "{\"transactionId\":\"...\"}",
"createdAt": "2024-01-15T10:10:00Z"
}
]
CampoDescrição
errorMessageMensagem resumida da última exceção
errorTraceStack trace completo
contextSnapshotJSON do contexto da saga no momento da falha

GET /api/dead-letters/{id}

Retorna uma dead letter específica pelo ID.

curl -H "Authorization: Bearer $TOKEN" /api/dead-letters/abc-...
  • 200 — dead letter encontrada
  • 404 — não existe

POST /api/dead-letters/{id}/reprocess

Marca a dead letter como reprocessada e reinicia o step correspondente na saga.

curl -X POST -H "Authorization: Bearer $TOKEN" /api/dead-letters/abc-.../reprocess
  • 202 — reprocessamento iniciado
  • 404 — dead letter não existe
O que acontece após o reprocessamento

A dead letter desaparece da fila pendente. O passo é re-executado com a política de retry configurada. O resultado (sucesso ou nova falha) aparece no log de eventos da saga em /api/sagas/{id}/events.


Próximos Passos