Action X-Ray

Integra à própria arquitetura uma visibilidade no nível de um debugger: o progresso de uma operação e seu state intermediário em cada passo ficam visíveis online — mesmo em produção, sem interromper o processo.

Uma operação de negócio complexa costuma ser uma cadeia de chamadas de método. Durante o desenvolvimento, você pode executá-la em um debugger, percorrer passo a passo todo o caminho de execução e ver o state intermediário. Isso ajuda a encontrar bugs complexos e não óbvios. Mas alguns problemas só aparecem com dados reais e sob carga real. Nesse momento, você precisa de um debugger online — capaz de radiografar a execução real da operação e encontrar a causa sem interromper o processo. O Action X-Ray oferece exatamente isso.

Documentação ↗

Em produção, não dá para acoplar um debugger

Um debugger mostra a operação por dentro — mas você não consegue acoplar um em produção, e uma execução ao vivo não oferece nada em que se apoiar.

Durante o desenvolvimento, um debugger congela a execução em qualquer passo: você vê os argumentos, os valores intermediários e o que será repassado adiante. Em produção isso é impossível — não é possível interromper o processo por causa de uma única requisição, e uma entrada rara é difícil de reproduzir. Nem é possível acompanhar a execução em tempo real: a cadeia de chamadas vive na call stack, seus valores intermediários em variáveis locais, e no instante em que uma chamada retorna, tudo isso desaparece. Os logs preservam apenas valores selecionados de antemão; um trace técnico vê as chamadas e sua duração, mas não sabe quais delas são passos de negócio nem quais valores intermediários entre elas importam. A causa precisa ser adivinhada a partir de pistas indiretas.

Os dados existem em tempo de execução — um debugger prova isso. O que falta é outra coisa: uma fronteira, conhecida de antemão, ao redor da execução e de cada um de seus passos, à qual se possa acoplar observação online — sem interromper o processo.

Desenvolvimento
validate
reservebreakpoint{ validated_items: 3 } · todos os valores visíveis
charge

pause em qualquer passo — todo o state fica visível

Produção
requisiçãoresposta / exceção

não dá para parar — o meio fica invisível

Documentação completa ↗

As fronteiras da execução já são definidas pela arquitetura

Para observar uma execução como um todo, ela precisa de uma fronteira precisa — e cada um de seus passos também.

No AOA, uma operação é uma Action com uma fronteira externa Params → Result. Ela é executada pela máquina — o motor do AOA que executa uma Action e sabe de antemão onde a execução começa e termina. Por dentro, o caminho é dividido em Aspects, cada um com seu próprio state intermediário, o state. Um Aspect recebe um snapshot do state anterior e retorna um novo state próprio — que substitui por completo o anterior, em vez de complementá-lo. Assim, tudo o que os passos seguintes precisam, o Aspect carrega adiante de forma explícita, e nada vaza entre os passos por conta própria; @result_* verifica a saída bem na fronteira. Essas fronteiras não são uma ferramenta de observação, mas a própria estrutura da operação; ainda assim, são exatamente elas que fornecem os pontos conhecidos de antemão onde ficam visíveis a entrada, a saída e o state de cada passo.

A qualquer momento, a máquina conhece a moldura da execução e todo o seu caminho contratual: o que entrou em cada Aspect e qual state saiu. O artefato observável “uma única execução” já é montado pela própria arquitetura — resta apenas liberá-lo para fora.

fronteira externa da Action
Params
state antes{ }
01 · ponto de observaçãovalidate@result_* ✓
state depois{ validated_items: 3 }
state antes{ validated_items: 3 }
02 · ponto de observaçãoreserve@result_* ✓
state depois{ …, reservation_id: 'res_42' }
state antes{ …, reservation_id: 'res_42' }
03 · ponto de observaçãocharge@result_* ✓
state depois{ …, payment_id: 'pay_91' }
Result
Documentação completa ↗

Debug online: uma execução ao vivo vista de fora

Como as fronteiras são conhecidas, a máquina emite um evento em cada uma delas — e um observador externo os reúne em uma imagem ao vivo da execução.

Na fronteira externa, você vê os Params e o Result reais; em cada fronteira interna, o state de entrada e de saída, a duração e qualquer erro. A máquina conhece todos esses pontos e emite automaticamente os lifecycle events; um plugin os recebe de fora e constrói uma projeção online de uma execução específica — uma árvore de passos com entradas, saídas, erros e tempos reais. O mesmo no desenvolvimento, nos testes e em produção — sem chamadas de log, cronômetros manuais ou código de tracing dentro dos métodos de negócio.

Isto não é um debugger acoplado nem um processo parado, mas sua projeção online segura. O observador vê apenas o que o contrato permite: campos sensíveis permanecem opacos, e uma falha do próprio plugin fica isolada e não altera o resultado da operação. É exatamente isso que é o Action X-Ray.

execução ao vivoCreateOrderAction
start · Paramsvalidate · state → state′ · 0.4 msreserve · state′ → state″ · 12 mscharge · error · 3 msfinish · Result · 15 ms
lifecycle events
plugin · fora da operaçãoprojeção online da execução
  • start · Params
  • validate · state → state′ · 0.4 ms
  • reserve · state′ → state″ · 12 msopaco
  • charge · error · 3 ms
  • finish · Result · 15 ms

o processo nunca é interrompido · o mesmo em dev, test e produção

O plugin é entregue à máquina na criação — os métodos de negócio permanecem intactos:

service/machine.py
plugin = OpenTelemetryPlugin(    tracer_provider=tracer_provider,    logger_provider=logger_provider,    service_name="checkout-service",)# The plugin lives outside the Action; business methods stay untouched.machine = ActionProductMachine(plugins=[plugin])result = await machine.run(Context(), CreateOrderAction(), params)
Documentação completa ↗

Em um teste — o mesmo raio-x

O mesmo snapshot online também está disponível em um teste: o TestBench executa a mesma operação pela mesma máquina.

O TestBench não cria uma visibilidade especial só para testes — ele executa a mesma Action pela mesma máquina e pelas mesmas fronteiras. Só o mundo externo muda: no lugar do Context, dos Resources e do gateway de produção, usam-se suas implementações de teste, enquanto os roles, o pipeline, os checkers e a montagem do Result continuam reais. A operação pode ser executada por completo ou interrompida em uma única fronteira — um Aspect, summary ou compensator — sem hooks especiais no código de negócio.

Um teste verifica a mesma projeção disponível em produção: não apenas o Result final, mas qualquer state intermediário. O que muda é a realidade ao redor da operação, não a operação em si nem a forma de observá-la.

PRODUÇÃOContext · Resources · Gateways reais
a mesma Action · a mesma máquinaroles · pipeline · checkers · montagem de Resultuma única e mesma projeção online
TESTEContext de teste · fixtures · mocks
a Action inteira — comportamento do sistemauma fronteira — localização precisa

A mesma Action pelo TestBench — por completo ou em uma única fronteira:

tests/test_create_order.py
inventory = AsyncMock(spec=InventoryGateway)inventory.reserve.return_value = "res_42"bench = TestBench().with_user(    user_id="customer", roles=(CustomerRole,)).with_mocks({InventoryGateway: inventory})# The whole operation — same machine, same boundariesresult = await bench.run(CreateOrderAction(), params, rollup=False)# Or stop at a single boundary and inspect its statestate_after = await bench.run_aspect(    CreateOrderAction(), "reserve_aspect",    params=params, state={"validated_items": 3},)assert state_after["reservation_id"] == "res_42"
Documentação completa ↗

O debug online se torna uma propriedade da arquitetura

O AOA define a fronteira externa de uma Action, as fronteiras internas de seus Aspects e transforma o state intermediário em um contrato. Durante uma execução, essas mesmas fronteiras se tornam o sistema de coordenadas para os lifecycle events — e a visibilidade que antes só surgia sob um debugger ou após instrumentação manual agora fica disponível online para cada execução, inclusive em produção, sem código de infraestrutura dentro da operação.

DepuraçãoPara uma execução específica, ficam visíveis o state antes e depois de cada passo, o erro e sua fronteira exata — sem acoplar um debugger.
ProduçãoA mesma projeção fica disponível online sob carga real por meio de plugins externos que não alteram a Action.
TestesVerificam-se a mesma operação e as mesmas fronteiras; apenas a realidade externa ao redor é substituída.
Action X-Ray · aoa.run