Engenharia · 10 min de leitura

Como criar uma taxonomia de eventos consistente

Aprenda a diferenciar tipo, grupo e classificação de eventos e veja como uma taxonomia consistente melhora a investigação e a leitura de dados.

Por Eyedux ·

Capa do artigo: Como criar uma taxonomia de eventos consistente

Você pode ter uma API bem documentada, uma boa cobertura de logs e milhares de eventos armazenados, mas ainda assim enfrentar uma investigação lenta. Basta que cada time nomeie seus eventos de um jeito diferente. Quando um fluxo usa order_failed, outro usa order.processing.error e um terceiro registra apenas error, seus dados deixam de formar uma linguagem comum.

Esse problema aparece quando a nomenclatura nasce de decisões locais e imediatas. Um desenvolvedor escolhe o nome mais conveniente para a integração que está implementando, outro copia um padrão antigo e, com o tempo, sua aplicação acumula eventos difíceis de comparar, filtrar e interpretar.

Uma taxonomia de eventos consistente resolve esse problema criando uma estrutura compartilhada. Você define como nomear o que aconteceu, como agrupar ocorrências relacionadas e como classificar a natureza de cada evento. Assim, sua equipe consegue investigar um caso específico sem perder a capacidade de enxergar padrões maiores.

O que é uma taxonomia de eventos

Taxonomia é uma forma organizada de classificar elementos que pertencem ao mesmo domínio. No caso dos eventos, ela define a linguagem usada para descrever ocorrências da sua aplicação e as dimensões que permitem navegar por elas.

Uma taxonomia não é apenas uma lista de nomes aprovados. Ela é um contrato de interpretação. Quando você registra order.processing.failed, seu time deve conseguir entender que o evento pertence ao processamento de um pedido e representa uma falha nesse fluxo. O nome não explica todos os detalhes, mas oferece um significado estável para iniciar a investigação.

Na Eyedux, essa organização fica dividida em três conceitos diferentes:

  • type: o tipo definido por você, com a nomenclatura própria do seu domínio.
  • type_group: o agrupamento opcional que reúne tipos relacionados.
  • eyedux_type: a classificação predefinida pela plataforma para indicar a natureza do evento.

Separar essas dimensões evita que você tente resolver problemas diferentes com um único campo. O tipo diz o que aconteceu no seu negócio, o grupo ajuda a organizar essa linguagem e a classificação predefinida cria uma perspectiva comum para segmentar os eventos.

Tipo, grupo e classificação não são a mesma coisa

type: sua taxonomia própria

O campo type é onde você expressa o vocabulário da sua aplicação. A Eyedux não impõe uma lista de tipos de negócio: você pode registrar order.processing.failed, subscription.renewed ou invoice.issued de acordo com os fluxos que importam para o seu produto.

Essa liberdade é importante porque o significado do evento depende do seu domínio. Uma plataforma não deveria decidir se uma ocorrência representa um pedido faturado, uma tentativa de ingestão ou uma alteração de contrato. Essa decisão pertence ao seu time e precisa refletir as perguntas que você fará durante uma investigação.

type_group: agrupamento lógico

O campo type_group é opcional e serve para você agrupar tipos relacionados. Ele pode reunir eventos de uma área ou fluxo maior, como orders, billing, ingestion ou authentication.

O grupo não substitui o tipo. Se você registra apenas orders, perde a distinção entre um pedido criado, processado, faturado ou rejeitado. O grupo funciona como uma camada de navegação: permite observar uma família de eventos enquanto o tipo preserva a precisão da ocorrência.

Como esse campo também é definido pelo cliente, você precisa estabelecer uma regra para ele. Use valores estáveis e reutilizáveis, em vez de frases livres, nomes de equipes ou identificadores que mudam a cada ocorrência. Se um evento não se encaixa em um grupo útil, deixar o campo vazio é melhor do que inventar uma classificação inconsistente.

eyedux_type: natureza predefinida do evento

O eyedux_type tem uma função diferente: ele não descreve o domínio da sua aplicação. Ele classifica a natureza do evento com um conjunto fixo de seis valores oferecidos pela Eyedux:

  • system-error: uma falha que exige investigação ou ação.
  • system-warning: uma condição de atenção que não representa necessariamente uma falha.
  • system-log: um registro operacional ou de execução.
  • system-debug: informação voltada à depuração.
  • system-info: uma informação relevante sobre o comportamento do sistema.
  • system-metric: uma medição ou sinal quantitativo.

Esses valores são predefinidos e não podem ser expandidos livremente pela sua aplicação. Você não deve usar eyedux_type para criar categorias como payment, order ou customer. Essas categorias pertencem ao seu type e, quando fizer sentido, ao seu type_group.

A classificação predefinida acrescenta uma lente comum sobre taxonomias diferentes. Times com domínios distintos podem usar nomes próprios, mas ainda conseguem separar erros, avisos, logs, depuração, informações e métricas da mesma maneira.

Como nomear tipos de eventos

O melhor nome é aquele que continua compreensível quando você o encontra meses depois, durante um incidente, sem precisar abrir o código que o produziu. Para chegar lá, trate a nomenclatura como uma decisão de contrato.

Use uma estrutura previsível

Uma convenção hierárquica com termos separados por ponto costuma funcionar bem para domínios com muitos fluxos. Em order.processing.failed, você identifica a entidade ou contexto, a operação e o resultado. O formato exato pode variar, mas precisa ser compartilhado por todos os produtores de eventos.

Defina também questões como plural ou singular, tempo verbal, separador, caixa das letras e idioma dos termos. A consistência dessas escolhas reduz consultas duplicadas e evita que duas grafias representem a mesma ideia.

Descreva o significado, não a implementação

O tipo deve registrar um acontecimento do seu domínio, não o nome de uma função ou arquivo. order.processing.failed tende a sobreviver a uma troca de linguagem ou de serviço. Já orders_processor.markRecordAsSkipped expõe detalhes internos que podem deixar de existir na próxima refatoração.

Também evite colocar no tipo valores que mudam a cada ocorrência. O código do pedido, a quantidade de retries e a mensagem de erro pertencem às propriedades. O tipo deve permanecer estável para que você consiga agrupar todas as ocorrências semanticamente equivalentes.

Escolha uma granularidade útil

Tipos amplos demais dificultam a investigação. Se tudo vira order, você não consegue distinguir uma criação de uma falha de processamento. Tipos detalhados demais também criam ruído: incluir o identificador do pedido, o número da tentativa ou o nome da função no tipo fragmenta seus dados em dezenas de categorias.

Uma boa pergunta é: qual decisão esse nome me ajuda a tomar? Se você precisa saber quais pedidos falharam durante o processamento, order.processing.failed oferece um recorte útil. Os detalhes que explicam aquela falha podem ficar em properties, metadata e referências ao objeto relacionado.

Documente exemplos e donos

Uma taxonomia só é consistente quando pessoas diferentes conseguem aplicá-la sem depender de memória ou de conversas antigas. Mantenha um catálogo com o nome do tipo, seu significado, exemplos de propriedades, classificação esperada e time responsável.

Esse catálogo também ajuda você a decidir quando criar um novo tipo. Antes de adicionar order.processing.retry_exhausted, verifique se ele representa um evento diferente ou apenas um detalhe de order.processing.failed. Se a diferença estiver nos dados da ocorrência, uma nova propriedade pode ser suficiente.

Por que classificar erros de forma predefinida

Os eventos de erro normalmente precisam de uma prioridade diferente dos demais. Eles podem representar perda de dados, interrupção de uma operação, falha de integração ou uma condição que seu time precisa acompanhar até ser resolvida. O eyedux_type permite segmentar esses eventos sem depender de palavras específicas dentro do seu type.

Quando um evento é classificado como system-error, a Eyedux também permite que você use o client_status para acompanhar a análise do erro. Os valores disponíveis são:

  • to_check: ainda precisa ser verificado.
  • solved: a investigação ou correção foi concluída.
  • declined: o time decidiu não tratar aquela ocorrência.

Esse campo é específico para eventos system-error. Um aviso, log, evento de debug, informação ou métrica não deve receber client_status como se estivesse no mesmo fluxo de triagem.

Não confunda estado interno com status de investigação

O campo status pertence ao estado interno do registro na Eyedux. No exemplo abaixo, active indica o estado do registro. Ele não diz se seu time investigou ou resolveu o problema.

client_status representa o acompanhamento feito por você sobre um evento de erro. No exemplo, to_check comunica que a ocorrência ainda precisa ser analisada. São campos com responsabilidades diferentes e não devem ser usados como sinônimos.

Um exemplo prático

Considere um evento de produção gerado depois que o processamento de um pedido atingiu o limite de retries:

{
  "status": "active",
  "eyedux_type": "system-error",
  "client_status": "to_check",
  "type": "order.processing.failed",
  "type_group": "",
  "environment": "production",
  "external_object": {
    "property": "id",
    "source": "database:business_xpto.orders"
  },
  "correlation_object": null,
  "properties": {
    "error": "Número máximo de retries atingido (3/3)",
    "operation": "order.processing.failed",
    "retry_count": 3,
    "order_status": "Invoiced"
  }
}

Nesse registro, order.processing.failed é o tipo definido pelo time que integra a aplicação. O campo type_group está vazio, então essa ocorrência não foi associada a um grupo opcional. O eyedux_type informa que a natureza do evento é um erro, enquanto client_status mostra que ele ainda está pendente de verificação.

O valor active em status não substitui to_check. O primeiro pertence ao registro interno; o segundo pertence ao processo de acompanhamento do erro. Essa distinção evita que uma consulta trate um evento ativo como necessariamente não investigado, ou um erro resolvido como removido da Eyedux.

Como a taxonomia melhora suas consultas

Quando as três dimensões estão bem definidas, você pode escolher o nível de detalhe da pergunta:

  • Use type para investigar um fluxo específico, como todos os eventos order.processing.failed.
  • Use type_group para observar uma família de fluxos relacionados, como todos os eventos de orders.
  • Use eyedux_type para separar a natureza dos eventos, como todos os system-error em produção.
  • Use client_status para acompanhar o trabalho pendente, resolvido ou recusado dentro do conjunto de erros.

Você também pode combinar esses recortes. Por exemplo, filtrar eventos system-error em produção, agrupar os tipos de processamento de pedidos e priorizar os que estão com client_status: to_check. O resultado não depende de interpretar mensagens livres ou procurar a palavra error dentro de cada nome.

Essa estrutura ajuda tanto uma investigação pontual quanto uma visão histórica. Você consegue comparar a ocorrência de um tipo ao longo do tempo, observar quais grupos concentram falhas e montar visualizações que continuam legíveis quando sua aplicação cresce.

Erros comuns ao desenhar sua taxonomia

  • Usar eyedux_type para representar entidades ou áreas do negócio.
  • Criar um novo type para cada mensagem de erro ou valor variável.
  • Deixar type_group virar um campo livre com nomes de times, incidentes e ambientes misturados.
  • Usar client_status em eventos que não são system-error.
  • Tratar o status interno do registro como se fosse o resultado da investigação.
  • Mudar o nome de um tipo existente sem avaliar o impacto nas consultas, views e comparações históricas.

O objetivo não é criar uma taxonomia perfeita antes de enviar seu primeiro evento. É estabelecer regras simples, registrar as decisões e evoluir o vocabulário sem quebrar o significado dos dados que você já acumulou.

Uma linguagem comum torna sua investigação escalável

Uma taxonomia consistente conecta a intenção do seu time aos dados que sua aplicação produz. type preserva a linguagem do seu domínio, type_group organiza tipos relacionados e eyedux_type oferece uma classificação estável para atravessar diferentes contextos.

Quando você mantém essas responsabilidades separadas, seus filtros ficam mais precisos, seus agrupamentos fazem mais sentido e seus erros deixam de ser apenas mensagens isoladas. A classificação não resolve sozinha a causa de um problema, mas reduz o caminho entre encontrar uma ocorrência e entender onde investigar.

Próximo conteúdo: continue a leitura sobre investigação com referências e correlação para entender como conectar um evento à entidade e à jornada que explicam o que aconteceu.