paint-brush
Monitorando Monolith com Datadog: como evitar o efeito espectadorpor@feddena
411 leituras
411 leituras

Monitorando Monolith com Datadog: como evitar o efeito espectador

por Fedor Denisov7m2024/07/08
Read on Terminal Reader

Muito longo; Para ler

Em grandes aplicações monolíticas, o rastreamento e o monitoramento de erros muitas vezes se tornam ineficazes devido à falta de propriedade clara. Este guia aborda o problema propondo uma abordagem estruturada para atribuir responsabilidades por meio de anotações de domínio introduzidas na biblioteca monolith-domain-splitter
featured image - Monitorando Monolith com Datadog: como evitar o efeito espectador
Fedor Denisov HackerNoon profile picture
0-item

Em grandes aplicações monolíticas, o rastreamento e o monitoramento de erros muitas vezes tornam-se ineficazes devido à falta de propriedade clara. Este guia aborda o problema propondo uma abordagem estruturada para atribuir responsabilidades por meio de anotações de domínio.


Configurar um monitoramento eficaz para grandes sistemas monolíticos com várias equipes pode ser um desafio. Sem uma propriedade clara, o rastreamento de erros torna-se genérico e muitas vezes ignorado. Uma solução é fazer com que engenheiros de plantão identifiquem qual equipe deve responder aos alarmes de monitoramento. No entanto, uma abordagem mais eficiente é incluir informações de domínio e equipe em cada log e intervalo do Datadog.


Compreendendo as anotações de domínio

Para saber qual equipe é responsável por diversas partes de nossa aplicação, usamos um sistema chamado Domain Annotations. As Anotações de Domínio rotulam cada parte do código do seu aplicativo, indicando claramente quem é responsável por quê. Isso fornece organização clara e responsabilidade no gerenciamento de responsabilidades.

Os benefícios do uso de anotações de domínio

As anotações de domínio fornecem um método claro e organizado para rastrear as responsabilidades da equipe em um aplicativo monolítico. Ao marcar partes do seu código com anotações de domínio, você pode:

  • Simplifique o gerenciamento de logs e rastreamentos : filtre logs e rastreamentos com base em critérios específicos, como responsabilidade da equipe, permitindo rápida identificação e resolução de problemas.
  • Mantenha um rastreamento preciso : adapte-se perfeitamente às mudanças nas responsabilidades da equipe, pois as anotações estão vinculadas ao domínio e não aos nomes da equipe.
  • Melhorar a responsabilidade : Defina claramente qual equipe é responsável por cada domínio, melhorando a organização e o monitoramento direcionado.
  • Melhorar a Eficiência da Monitorização : Facilitar melhores práticas de monitorização, proporcionando uma responsabilização precisa e melhorando a eficiência global.

Processamento de anotações de domínio

Para garantir monitoramento e rastreabilidade eficientes, cada solicitação da web é marcada com as informações de domínio apropriadas. Isto é conseguido através da colaboração de vários componentes: DomainProvider , DomainSpanService , DomainMdcProvider e DomainHandlerInterceptor .

Aqui está uma visão geral de alto nível do processo descrito no diagrama a seguir:

Diagrama de processamento de anotações de domínio

Explicação dos principais componentes

  • DomainProvider : identifica o domínio associado a métodos manipuladores ou beans específicos. Ajuda a encontrar anotações de domínio em chamadas AOP (Aspect-Oriented Programming) e MVC (Model-View-Controller).
  • DomainSpanService : adiciona tags de domínio a spans, que são unidades de trabalho em sistemas de rastreamento. Este serviço garante que cada período seja marcado com as informações de domínio apropriadas.
  • DomainMdcProvider : gerencia tags de domínio dentro do MDC (Mapped Diagnostic Context), um recurso de estruturas de log que permite marcar entradas de log com informações contextuais.
  • DomainHandlerInterceptor : intercepta solicitações da web, garantindo que cada solicitação seja marcada com as informações de domínio apropriadas para melhor monitoramento e rastreabilidade.

A implementação detalhada desses componentes será encapsulada em uma biblioteca compartilhada, fornecendo uma solução reutilizável para marcação e monitoramento de solicitações da Web em grandes aplicações monolíticas.

Classificando quem possui qual código

Definir a propriedade no nível da classe é simples com anotações de domínio. Ao aplicar anotações de nível superior às classes principais, a propriedade se propaga para todos os recursos detalhados dentro dessas classes. Cada equipe pode rotular as classes de sua propriedade com as anotações de domínio apropriadas, garantindo clareza e responsabilidade sem a necessidade de marcar cada método.


Nos casos em que várias equipes possuem código em uma classe e a refatoração imediata não é apropriada, você pode marcar métodos individuais com anotações de domínio diferentes, que têm prioridade sobre as anotações em nível de classe. Isto permite que métodos específicos sejam atribuídos a diferentes equipes, proporcionando flexibilidade sem complicar a estrutura geral.

Superando casos não suportados por anotações

Embora as anotações de domínio sejam extremamente úteis, há casos raros em que elas não podem ser usadas. Por exemplo, encontramos problemas com a criação de trabalhos do Quartz, que não funcionavam perfeitamente com anotações de domínio devido a um conflito entre a lógica AOP do Quartz e a lógica AOP usada para anotações de domínio.

Para jobs e processos que não podem ser anotados diretamente, utilizamos o DomainTagsService diretamente nas implementações dos jobs. Essa abordagem nos permitiu adicionar manualmente tags de domínio à lógica de execução do trabalho.

Aqui está um exemplo de como integramos DomainTagsService em um trabalho Quartz:

 final override fun execute(context: JobExecutionContext) { domainTagsService.invoke(domain) { withLoggedExecutionDetails(context, ::doExecute) } }

Melhore o monitoramento e a visibilidade com serviços artificiais

Embora ter serviços separados para cada equipe ofereça vantagens significativas no monitoramento e na propriedade, isso acarreta altos custos e esforços para dividir o monólito, juntamente com possíveis despesas adicionais de desenvolvimento. Considerando a possibilidade de melhorar os tempos de construção com Gradle quando o monólito é dividido em módulos, manter um monorepo pode ser a solução mais eficiente em muitos casos.

Introdução de serviços artificiais

Para simplificar o monitoramento das atividades de cada equipe no Datadog, você pode atribuir nomes de serviço artificiais para períodos de equipes diferentes. Essa abordagem garante que cada equipe tenha sua própria seção dedicada nas ferramentas de monitoramento do Datadog. Embora o uso de nomes de serviços artificiais possa ser confuso se você tiver muitos serviços para gerenciar, ele se torna gerenciável com um número limitado de serviços de back-end. Adicionar prefixos a esses nomes de serviço artificiais ajuda a manter a organização e a clareza na configuração do Datadog, tornando mais fácil distinguir entre diferentes equipes e suas responsabilidades.


usar o diagrama em vez da captura de tela? ter trabalhador/webapp não faz sentido aqui

Serviços artificiais no Datadog APM que são na verdade um único aplicativo

Por que não usar serviços artificiais para logs?

Usar nomes de serviço artificiais para logs pode criar confusão, pois a mesma entrada de log pode aparecer em serviços diferentes.


Por exemplo, considere dois endpoints usando o mesmo serviço de autenticação. Se esses endpoints forem anotados com domínios diferentes, a lógica de autenticação produzirá logs sob diferentes serviços artificiais. Isso pode causar confusão ao explorar os logs, pois eles aparecem sob vários nomes de serviço. Para evitar esse problema, é melhor aplicar nomes de serviço artificiais apenas a intervalos agregados em rastreamentos, para que haja menos confusão


Isto faz algum sentido? Eu não acho que seja


Aqui está uma representação visual deste problema:

Raciocínio por trás do não uso de serviços artificiais para logs

Usando Serviços Artificiais em Monitoramento e Dashboards

O uso de serviços artificiais permite não apenas trabalhar com rastreamentos de APM, mas também filtrar por serviço nas métricas do Datadog, que são armazenadas por um período prolongado, permitindo o rastreamento de alterações por um período prolongado.

Exemplo de monitor

Abaixo está uma captura de tela de um monitor no Datadog que usa o nome de serviço artificial konsus-assets na consulta:

Monitor que utiliza serviço artificial 'konsus-assets' na consulta

Exemplo de painel

Abaixo está uma captura de tela de um painel no Datadog que usa o nome de serviço artificial konsus-assets no filtro:

Painel que usa serviço falso 'konsus-assets' no filtro

Ao utilizar serviços falsos em sua estratégia de monitoramento, você pode aumentar a visibilidade e a responsabilidade das atividades de cada equipe em um aplicativo monolítico. Essa abordagem simplifica o processo de criação e manutenção de monitores e painéis específicos da equipe, levando a um monitoramento mais eficaz e organizado no Datadog.


Empacotando

As anotações de domínio fornecem uma abordagem direta para simplificar o monitoramento de aplicativos monolíticos no Datadog. Ao implementar esta estratégia, você pode melhorar a capacidade de gerenciamento de logs, spans e métricas, transformando sua configuração de monitoramento em uma ferramenta adaptada para equipes específicas. Isso melhora a responsabilidade e a organização e facilita a solução de problemas e a análise de desempenho de forma mais eficaz e eficiente em todo o seu aplicativo.

Principais conclusões

  1. Propriedade e responsabilidade aprimoradas : ao anotar partes do seu código com anotações de domínio, você pode definir claramente qual equipe é responsável por cada domínio. Isto facilita uma melhor organização e um monitoramento direcionado.
  2. Gerenciamento aprimorado de logs e rastreamentos : as anotações de domínio permitem filtrar logs e rastreamentos com base em critérios específicos, como responsabilidade da equipe, permitindo rápida identificação e resolução de problemas.
  3. Flexibilidade com serviços artificiais : o uso de nomes de serviços artificiais para spans (não logs) garante que os logs permaneçam claros e rastreáveis até suas verdadeiras origens, evitando confusão.
  4. Superando desafios de integração : para casos em que as anotações não podem ser aplicadas diretamente, como em certas estruturas de execução de trabalhos como o Quartz, o uso de serviços como DomainTagsService diretamente nas implementações de trabalhos garante que o monitoramento específico do domínio ainda possa ser mantido.

Abordagem passo a passo para usar anotações de domínio:

  1. Definir Domínios e Equipes

    Isso vai mudar com a lib!!!

    Crie enums representando diferentes domínios e equipes em seu aplicativo:

    • @Domain é uma anotação que pode ser aplicada a classes ou funções, marcando-as com um valor de domínio específico.
    • DomainValue é um enum que representa diferentes domínios, cada um associado a uma equipe.
    • Team é um enum que representa as diversas equipes que trabalham no aplicativo.
     @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class Domain(val value: DomainValue) enum class DomainValue(val team: Team) { USER_MANAGEMENT(Team.TEAM_A), PAYMENT_PROCESSING(Team.TEAM_B), NOTIFICATIONS(Team.TEAM_C) } enum class Team { TEAM_A, TEAM_B, TEAM_C }
  2. Anote classes (e métodos, se necessário)

     @Domain(DomainValue.USER_MANAGEMENT) class UserService { @Domain(DomainValue.PAYMENT_PROCESSING) fun processPayment() { ... } }
  3. Lidar com casos não suportados

    Para casos que não podem ser anotados diretamente, use DomainTagsService diretamente para encapsular a lógica

     fun executeNotSupportedByAnnotationsLogic() { domainTagsService.invoke(domain) { executeLogic() } }
  4. Monitore com Datadog

    Use filtros de serviço artificiais para filtros de monitores, painéis e rastreamentos de APM


Seguindo essas etapas, você pode implementar efetivamente anotações de domínio em seu aplicativo monolítico, garantindo monitoramento, responsabilidade e eficiência geral aprimorados.


Obrigado por ler o post!