Padrões de observabilidade
Gorjeta
Este conteúdo é um excerto do eBook, Architecting Cloud Native .NET Applications for Azure, disponível no .NET Docs ou como um PDF transferível gratuito que pode ser lido offline.
Assim como os padrões foram desenvolvidos para ajudar no layout do código em aplicativos, existem padrões para operar aplicativos de forma confiável. Três padrões úteis na manutenção de aplicativos surgiram: registro, monitoramento e alertas.
Quando usar o registro em log
Não importa o quão cuidadosos sejamos, os aplicativos quase sempre se comportam de maneiras inesperadas na produção. Quando os usuários relatam problemas com um aplicativo, é útil poder ver o que estava acontecendo com o aplicativo quando o problema ocorreu. Uma das maneiras mais testadas e verdadeiras de capturar informações sobre o que um aplicativo está fazendo enquanto está em execução é fazer com que o aplicativo anote o que está fazendo. Esse processo é conhecido como registro. Sempre que ocorrerem falhas ou problemas na produção, o objetivo deve ser reproduzir as condições em que as falhas ocorreram, em um ambiente não produtivo. Ter um bom registro em prática fornece um roteiro para os desenvolvedores seguirem a fim de duplicar problemas em um ambiente que pode ser testado e experimentado.
Desafios ao registrar com aplicativos nativos da nuvem
Em aplicativos tradicionais, os arquivos de log geralmente são armazenados na máquina local. Na verdade, em sistemas operacionais Unix-like, há uma estrutura de pastas definida para armazenar quaisquer logs, normalmente em /var/log
.
Figura 7-1. Registro em log em um arquivo em um aplicativo monolítico.
A utilidade de registrar em um arquivo simples em uma única máquina é muito reduzida em um ambiente de nuvem. Os aplicativos que produzem logs podem não ter acesso ao disco local ou o disco local pode ser altamente transitório, pois os contêineres são embaralhados em torno de máquinas físicas. Mesmo a simples expansão de aplicativos monolíticos em vários nós pode dificultar a localização do arquivo de log baseado em arquivo apropriado.
Figura 7-2. Registro em arquivos em um aplicativo monolítico dimensionado.
Os aplicativos nativos da nuvem desenvolvidos usando uma arquitetura de microsserviços também representam alguns desafios para os registradores baseados em arquivos. As solicitações do usuário agora podem abranger vários serviços que são executados em máquinas diferentes e podem incluir funções sem servidor sem acesso a um sistema de arquivos local. Seria muito desafiador correlacionar os logs de um usuário ou de uma sessão nesses muitos serviços e máquinas.
Figura 7-3. Registro em arquivos locais em um aplicativo de microsserviços.
Finalmente, o número de usuários em alguns aplicativos nativos da nuvem é alto. Imagine que cada usuário gera cem linhas de mensagens de log quando faz login em um aplicativo. Isoladamente, isso é gerenciável, mas multiplique mais de 100.000 usuários e o volume de logs se torne grande o suficiente para que ferramentas especializadas sejam necessárias para dar suporte ao uso eficaz dos logs.
Iniciar sessão em aplicações nativas da nuvem
Toda linguagem de programação tem ferramentas que permitem escrever logs e, normalmente, a sobrecarga para gravar esses logs é baixa. Muitas das bibliotecas de registro em log fornecem diferentes tipos de criticidades, que podem ser ajustadas em tempo de execução. Por exemplo, a biblioteca Serilog é uma biblioteca de log estruturada popular para .NET que fornece os seguintes níveis de log:
- Verboso
- Depurar
- Informações
- Aviso
- Erro
- Fatal
Esses diferentes níveis de log fornecem granularidade no registro em log. Quando o aplicativo está funcionando corretamente na produção, ele pode ser configurado para registrar apenas mensagens importantes. Quando o aplicativo está se comportando mal, o nível de log pode ser aumentado para que mais logs detalhados sejam coletados. Isso equilibra o desempenho com a facilidade de depuração.
O alto desempenho das ferramentas de registro e a ajustabilidade da verbosidade devem incentivar os desenvolvedores a registrar com frequência. Muitos preferem um padrão de registro da entrada e saída de cada método. Essa abordagem pode parecer exagero, mas é raro que os desenvolvedores desejem menos registro. Na verdade, não é incomum executar implantações com o único propósito de adicionar o log em torno de um método problemático. Erre pelo lado de muito registro e não por muito pouco. Algumas ferramentas podem ser usadas para fornecer automaticamente esse tipo de registro.
Devido aos desafios associados ao uso de logs baseados em arquivos em aplicativos nativos da nuvem, os logs centralizados são preferidos. Os logs são coletados pelos aplicativos e enviados para um aplicativo de log central que indexa e armazena os logs. Esta classe de sistema pode ingerir dezenas de gigabytes de logs todos os dias.
Também é útil seguir algumas práticas padrão ao criar logs que abrangem muitos serviços. Por exemplo, gerar um ID de correlação no início de uma longa interação e, em seguida, registrá-lo em cada mensagem relacionada a essa interação, facilita a pesquisa de todas as mensagens relacionadas. Basta encontrar uma única mensagem e extrair o ID de correlação para encontrar todas as mensagens relacionadas. Outro exemplo é garantir que o formato de log seja o mesmo para todos os serviços, independentemente do idioma ou da biblioteca de log usada. Essa padronização torna a leitura de logs muito mais fácil. A Figura 7-4 demonstra como uma arquitetura de microsserviços pode aproveitar o registro centralizado como parte de seu fluxo de trabalho.
Figura 7-4. Os logs de várias fontes são ingeridos em um armazenamento de log centralizado.
Desafios para detetar e responder a possíveis problemas de integridade do aplicativo
Alguns aplicativos não são de missão crítica. Talvez eles sejam usados apenas internamente e, quando ocorre um problema, o usuário pode entrar em contato com a equipe responsável e o aplicativo pode ser reiniciado. No entanto, os clientes geralmente têm expectativas mais altas para os aplicativos que consomem. Você deve saber quando ocorrem problemas com seu aplicativo antes que os usuários o notifiquem. Caso contrário, o primeiro que você sabe sobre um problema pode ser quando você percebe um dilúvio furioso de postagens de mídia social ridicularizando seu aplicativo ou até mesmo sua organização.
Alguns cenários que você pode precisar considerar incluem:
- Um serviço em seu aplicativo continua falhando e reiniciando, resultando em respostas lentas intermitentes.
- Em alguns momentos do dia, o tempo de resposta do seu aplicativo é lento.
- Após uma implantação recente, a carga no banco de dados triplicou.
Implementado corretamente, o monitoramento pode informá-lo sobre condições que levarão a problemas, permitindo que você resolva as condições subjacentes antes que elas resultem em qualquer impacto significativo para o usuário.
Monitoramento de aplicativos nativos da nuvem
Alguns sistemas de registro centralizado assumem um papel adicional de coletar telemetria fora dos logs puros. Eles podem coletar métricas, como tempo para executar uma consulta de banco de dados, tempo médio de resposta de um servidor Web e até mesmo médias de carga da CPU e pressão de memória, conforme relatado pelo sistema operacional. Em conjunto com os logs, esses sistemas podem fornecer uma visão holística da integridade dos nós no sistema e no aplicativo como um todo.
Os recursos de coleta de métricas das ferramentas de monitoramento também podem ser alimentados manualmente de dentro do aplicativo. Os fluxos empresariais que se revistam de especial interesse, como a adesão de novos utilizadores ou a realização de encomendas, podem ser instrumentados de modo a incrementar um contador no sistema central de monitorização. Esse aspeto desbloqueia as ferramentas de monitoramento para monitorar não apenas a integridade do aplicativo, mas a saúde do negócio.
As consultas podem ser construídas nas ferramentas de agregação de logs para procurar determinadas estatísticas ou padrões, que podem ser exibidos em forma gráfica, em painéis personalizados. Frequentemente, as equipas investem em grandes ecrãs montados na parede que rodam através das estatísticas relacionadas com uma aplicação. Desta forma, é simples ver os problemas à medida que ocorrem.
As ferramentas de monitoramento nativas da nuvem fornecem telemetria em tempo real e informações sobre aplicativos, independentemente de serem aplicativos monolíticos de processo único ou arquiteturas de microsserviços distribuídos. Eles incluem ferramentas que permitem a coleta de dados do aplicativo, bem como ferramentas para consultar e exibir informações sobre a integridade do aplicativo.
Desafios para reagir a problemas críticos em aplicativos nativos da nuvem
Se você precisa reagir a problemas com seu aplicativo, você precisa de alguma maneira de alertar o pessoal certo. Este é o terceiro padrão de observabilidade de aplicativos nativos da nuvem e depende do registro em log e do monitoramento. Seu aplicativo precisa ter o registro em log para permitir que os problemas sejam diagnosticados e, em alguns casos, para alimentar as ferramentas de monitoramento. Ele precisa de monitoramento para agregar métricas de aplicativos e dados de integridade em um só lugar. Uma vez que isso tenha sido estabelecido, podem ser criadas regras que dispararão alertas quando determinadas métricas estiverem fora dos níveis aceitáveis.
Geralmente, os alertas são sobrepostos ao monitoramento, de modo que certas condições acionam alertas apropriados para notificar os membros da equipe sobre problemas urgentes. Alguns cenários que podem exigir alertas incluem:
- Um dos serviços do seu aplicativo não está respondendo após 1 minuto de tempo de inatividade.
- Seu aplicativo está retornando respostas HTTP malsucedidas para mais de 1% das solicitações.
- O tempo médio de resposta do seu aplicativo para os principais pontos de extremidade excede 2000 ms.
Alertas em aplicações nativas da nuvem
Você pode criar consultas nas ferramentas de monitoramento para procurar condições de falha conhecidas. Por exemplo, as consultas podem procurar nos logs de entrada indicações do código de status HTTP 500, que indica um problema em um servidor web. Assim que um deles é detetado, então um e-mail ou um SMS pode ser enviado para o proprietário do serviço de origem, que pode começar a investigar.
Normalmente, porém, um único erro 500 não é suficiente para determinar que ocorreu um problema. Isso pode significar que um usuário digitou incorretamente sua senha ou inseriu alguns dados malformados. As consultas de alerta podem ser criadas para serem acionadas somente quando um número maior do que a média de 500 erros for detetado.
Um dos padrões mais prejudiciais no alerta é disparar muitos alertas para os humanos investigarem. Os proprietários de serviços rapidamente se tornarão insensíveis a erros que eles investigaram anteriormente e descobriram ser benignos. Então, quando erros verdadeiros ocorrem, eles serão perdidos no barulho de centenas de falsos positivos. A parábola do Menino que Chorou Lobo é frequentemente contada às crianças para alertá-las desse perigo. É importante garantir que os alertas que disparam são indicativos de um problema real.