Pular para o conteúdo principal

Eventos de Negócio

Custo isolado não diz se um investimento em tecnologia foi bom ou ruim — precisa de contexto de negócio. O CloudBroker usa o mesmo Financial Event Bus que recebe custo de conector pra receber eventos de negócio (deploy, análise de PR, custo por feature), correlacionados por tempo.

De onde vêm hoje​

  • Deploy concluído (deployment.completed): um passo no final do job de deploy do seu CI chama POST /api/deploys/completed. É o único sinal de deploy real — veja Registrando deploys abaixo.
  • Análise de PR (deployment.created): publicado quando a análise de custo de PR roda (POST /api/analyze/pr, chamado pelo workflow de análise em cada PR aberta ou atualizada, ou pelo trackDeploy do SDK). Apesar do nome do evento, ele marca uma PR analisada, não um deploy — a PR pode ser mergeada dias depois, ou nunca. Na Timeline aparece como "PR analisada".
  • Custo por feature: via wrapAWS/expressMiddleware do SDK — cada chamada de nuvem herda um label de negócio (produto, squad, trecho)
  • Anomalias: detectadas automaticamente pelos conectores de cloud (AWS, Azure), e os picos de custo diário viram Findings

Registrando deploys​

A tela Deploy & PR tem o card Registrar deploys, com o trecho pronto para copiar. Adicione-o ao final do job que faz o deploy em produção (não ao workflow de PR):

# Adicione ao FINAL do job que faz o deploy em produção.
# Envia repo, commit e a LISTA DE CAMINHOS alterados — nunca o conteúdo.
- name: CloudBroker — registra deploy concluído
if: success()
continue-on-error: true
env:
CB_BEFORE: ${{ github.event.before }}
CB_SHA: ${{ github.sha }}
run: |
CHANGES=null
if [ -n "$CB_BEFORE" ] && [ "$CB_BEFORE" != "0000000000000000000000000000000000000000" ]; then
git cat-file -e "$CB_BEFORE^{commit}" 2>/dev/null || git fetch -q --depth=1 origin "$CB_BEFORE" 2>/dev/null || true
# -z + core.quotePath=false: caminho com acento ou quebra de linha
# chega inteiro, não como "src/a\303\247ao.js" entre aspas.
CB_DIFF="${RUNNER_TEMP:-/tmp}/cb-diff"
if git -c core.quotePath=false diff --name-only -z "$CB_BEFORE" "$CB_SHA" > "$CB_DIFF" 2>/dev/null; then
CHANGES=$(jq -Rs --arg before "$CB_BEFORE" 'split("\u0000") | map(select(length > 0)) | {before:$before, files:.[:300], truncated:(length > 300)}' < "$CB_DIFF") || CHANGES=null
fi
fi
# Qualquer falha acima registra o deploy SEM a lista (fail-open) —
# nunca aborta o passo antes do curl (bash -e).
printf '%s' "$CHANGES" | jq -e 'type == "object" or . == null' > /dev/null 2>&1 || CHANGES=null
curl -sS --max-time 30 -X POST https://api.cloudbroker.app.br/api/deploys/completed \
-H "Content-Type: application/json" \
-H "x-api-key: ${{ secrets.CLOUDBROKER_API_KEY }}" \
-d "$(jq -n \
--arg repo "${{ github.repository }}" \
--arg sha "${{ github.sha }}" \
--arg ref "${{ github.ref }}" \
--arg actor "${{ github.actor }}" \
--argjson changes "$CHANGES" \
'{repo:$repo,sha:$sha,ref:$ref,actor:$actor,environment:"production"} + (if $changes == null then {} else {changes:$changes} end)')" \
|| echo "::warning::CloudBroker indisponível — deploy não registrado (fail-open)."
  • API key do tipo SDK, guardada como secret do repositório (CLOUDBROKER_API_KEY) — nunca cole a key no arquivo. Key do tipo MCP é recusada (403).
  • Só depois do deploy dar certo (if: success()), e fail-open: se o CloudBroker estiver fora do ar, o seu deploy não falha.
  • Campos: repo (formato owner/nome) e sha (hash do commit, 7 a 40 caracteres hexadecimais) são obrigatórios. environment é opcional (padrão production); ref e actor são opcionais.
  • Idempotente: o mesmo repo + sha + environment vira um único evento. Job re-executado ou reenvio não conta o deploy duas vezes (a resposta traz duplicate: true). O mesmo commit em staging e em production são dois deploys distintos.
  • O que mudou (changes, opcional): o passo manda a lista de caminhos alterados desde o push anterior (git diff --name-only), nunca o conteúdo dos arquivos. Sem commit anterior, ou se a montagem da lista falhar, o deploy é registrado sem ela.

O que o CloudBroker faz com a lista de arquivos​

Cada caminho é classificado numa categoria: infra (Terraform, CloudFormation, CDK, Pulumi), container (Dockerfile, compose, Kubernetes/Helm, task definition), dependências (package.json, lockfiles, requirements.txt, go.mod…), CI, config, docs e código. Ficam guardadas só as contagens por categoria e até 20 caminhos de infra, container e dependências — caminho de código não é guardado.

  • Até 300 caminhos por deploy; acima disso o resumo é marcado como truncado.
  • Caminho com acento é aceito. Caminho ilegível (caractere de controle, .., espaço) não é guardado: é contado como "ilegível", e o resumo deixa de servir para afirmar que nada de infra mudou.
  • O resumo é completo quando o commit anterior informado é o último deploy registrado do mesmo repositório e ambiente. Se houve deploy no meio sem registro, a lista não cobre tudo, e o CloudBroker diz isso.
  • Deploy sem a lista aparece como "não informado", nunca como "nada mudou".

Onde os deploys aparecem​

  • Deploy & PR → Deploys registrados: os deploys da janela, com as categorias que cada um mudou e os caminhos de infra/dependências. A linha de cobertura diz desde quando há registro — lista vazia não prova que não houve deploy.
  • API: GET /api/deploys/completed?days=30 (1 a 60 dias). Se o registro estiver indisponível, a resposta é 503, nunca uma lista vazia.
  • MCP: a tool list_deploys.
O histórico começa quando você adiciona o passo

Não existe registro retroativo: deploys anteriores à inclusão do passo no CI não aparecem na correlação.

Como isso vira decisão​

O Correlation Engine cruza esses eventos por janela de tempo, usando só deployment.completed como deploy:

  • Root Cause — para um evento de custo, busca os deploys concluídos nas 48 horas anteriores (janela ajustável até 7 dias pela API) como candidatos a causa. Se a fonte de deploys estiver indisponível, a resposta diz que não deu para verificar (deploysAvailable: false), em vez de afirmar que não houve deploy.
  • Impacto de deploy (Visão Geral) — compara a média diária do custo por código (via SDK) nos 3 dias antes com os 3 dias a partir de cada dia com deploy. Sem dado suficiente de um dos lados, o impacto não é calculado.

O FinOps Advisor usa essa correlação pra responder perguntas como "por que o custo do Checkout subiu essa semana?" com uma causa provável, não só o número. Coincidência de janela não prova causalidade — é um candidato a investigar.

Próximo passo​

Para deploys, adicione o passo acima ao seu CI. Para custo por feature, comece pelo SDK — é o que gera os eventos de negócio do lado da sua aplicação.