O blog da AWS

Faça o stream de logs para uma conta centralizada utilizando serviços Serverless

Por Amanda Quinto, arquiteta de soluções da AWS;

Por Gabriel Bella Martini, arquiteto de soluções da AWS

A utilização de múltiplos estilos e padrões de arquitetura, tais como, microsserviços, mensagens,  e outros, podem gerar ambientes complexos devido a alta quantidade de componentes, em hosts ou serviços distintos. Consequentemente, em um cenário de alta complexidade torna-se desafiador a identificação de problemas e seus impactos em uma aplicação. A utilização é uma maneira simples de identificar a causa-raiz de problemas que possam estar ocorrendo no ambiente. Através de Logs centralizados, você poderá obter  maior visibilidade do ambiente, permitindo a realização de auditoria e maior velocidade na identificação de  problemas dentro de arquiteturas distribuídas.

Os logs fazem parte de uma prática maior chamada de observability, que aborda a identificação proativa através do monitoramento, alertas, telemetria, detecção de anomalias entre outras práticas e ferramentas que irão ajudar na detecção e investigação de problemas. Na AWS, os clientes podem utilizar serviços como Amazon CloudWatch e Amazon OpenSearch para a centralização de logs no entanto, alternativamente, há clientes optam por  mover para uma solução própria para centralização de logs, visando a customização dos logs, otimização de custos, o uso de diferentes aplicações clientes para consumo das informações e o armazenamento em longo prazo doslogs, entre diferentes contas AWS e diferentes serviços.

Neste blog post, abordaremos a criação de uma arquitetura serverless para centralização de logs em um ambiente de múltiplas contas AWS. O conteúdo deste blog post, parte do princípio que você tenha algum conhecimento de Amazon CloudFormation e Amazon Athena. Os templates do CloudFormation, o exemplo que será demonstrado para Amazon EC2 Container Service (ECS) e outros exemplos como logs para AWS Lambda e Amazon EC2, que não serão abordados neste blog post, podem ser encontrados neste repositório do GitHub.

Visão geral da solução

O diagrama abaixo ilustra a arquitetura da solução, coletando os logs de diferentes serviços da Conta de Aplicação e efetuando a ingestão de forma centralizada na Conta de Logging.

O fluxo da arquitetura segue da seguinte forma:

  1. A conta de aplicação do lado esquerdo representa uma conta AWS que irá conter os componentes de aplicação, por exemplo, funções Lambda, containers, máquinas virtuais e qualquer outro serviço que produza
  2. Nesta solução será utilizado o Amazon Kinesis Data Firehose na conta de Logging para ingestão dos logs. A integração ao Kinesis Firehose dependerá de cada componente produtor de log. Os produtores testados são ECS, Lambda, EC2 e Amazon API Gateway. O Kinesis Firehose receberá os logs e efetuar a ingestão em um bucket do Amazon S3, sendo esses logs enviados de acordo com o tamanho do buffer (1 MiB até 128 MiB) ou após um intervalo de tempo (60 segundos até 900 segundos). Outra definição que pode ser feita para o Kinesis Firehose, é o prefixo de armazenamento, podendo particionar o dado no S3. Para este exemplo, o seguinte prefixo será utilizado:

logging/year=!{timestamp:yyyy}/month=!{timestamp:MM}/day=!{timestamp:dd}/hour=!{timestamp:HH}/

  1. Com os dados armazenados e particionados no S3, a solução irá executar um Crawler do AWS Glue para criar um catálogo que possibilite o consumo destes logs no S3.
  2. Após a criação do catálogo, o time de desenvolvimento poderá analisar os logs através de queries SQL utilizando o Athena.

Passo a passo

A implantação desta solução será dividida em três etapas:

  1. Execução do CloudFormation na conta de Logging;
  2. Criação de uma aplicação de exemplo na conta de Aplicação;
  3. Análise dos logs gerados.

Pré-requisitos

Para seguir o passo a passo veja os seguintes pré-requisitos:

Obs.: O objetivo deste blog post é demonstrar a centralização dos logs em um ambiente de múltiplas contas AWS, no entanto, é também possível implementar a solução em uma única conta AWS.

Execução do CloudFormation na Conta de Logging

Siga os passos abaixo para criar os recursos da Conta de Logging:

  1. Na Conta de Logging crie uma stack do CloudFormation utilizando o template do repositório. Os seguintes recursos serão criados pela stack:
    • AWS IAM role e permissões: Função IAM com permissões para o Kinesis Firehose, Glue e acesso entre contas;
    • S3: Bucket do S3 com ciclo de vida para armazenamento dos logs;
    • Glue: Crawler para criação do catálogo de logs;
    • Kinesis Firehose: Criação de um Delivery
  2. No parâmetro ApplicationAccount adicione o Account ID da Conta de Aplicação (se estiver fazendo a implementação na mesma conta de aplicação, deixe este valor em branco). Caso queira especificar uma retenção maior para os logs, modifique o valor do parâmetro LogsLifeCycle (padrão em 30 dias).
  3. Anote os valores ApplicationAccountRoleArn e KinesisFirehoseECSName encontrados na aba de output após a execução da stack. Estes valores serão utilizados posteriormente.

Criação de uma aplicação de exemplo na Conta de Aplicação

Nesta etapa será implementada uma aplicação em Python através do Amazon ECS. s O roteador de logs FireLens,em conjunto com o projeto FluentBit, será utilizado para enviar os logs da aplicação para a solução centralizada de logging.

Para aprofundamento no funcionamento do FireLens sugerimos a leitura deste blog postUnder the hood: FireLens for Amazon ECS Tasks”.

Execute os passos abaixo:

  1. Na Conta de Aplicação crie uma stack do CloudFormation utilizando o template para ECS do repositório. Os seguintes recursos serão criados pela stack:
    • a) VPC e recursos de rede;
    • b) IAM role e permissões;
    • c) Repositório do Amazon ECR;
    • d) Cluster do ECS.
  1. No parâmetro ApplicationAccountRoleArn adicione o ApplicationAccountRoleArn anotado no passo 3 da etapa anterior (se estiver fazendo a implantação na mesma conta de aplicação, deixe este valor em branco);
  2. Anote todos os valores encontrados na aba de output após a execução da stack;
  3. Substitua os valores destacados e execute os seguintes comandos para build e push da imagem de container da aplicação:
a) cd aws-serverless-centralized-logs/samples/ecs
b) aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
c) docker build -t repository-ACCOUNT_ID .
d) docker tag repository-ACCOUNT_ID:latest ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/repository-ACCOUNT_ID:latest
e) docker push ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/repository-ACCOUNT_ID:latest
  1. Preencha os valores destacados de acordo com o output do passo 3 de ambas as etapas no arquivo container-definition.json:
{
  "family": "ecs-sample-log",
  "executionRoleArn": "IAMRole",
  "taskRoleArn": "IAMRole",
  "networkMode": "awsvpc",
  "cpu": "256",
  "memory": "512",
  "requiresCompatibilities": ["FARGATE"],
  "containerDefinitions": [
    {
      "logConfiguration": {
        "logDriver": "awsfirelens",
        "options": {
          "delivery_stream": "KinesisFirehoseECSName",
          "region": "us-east-1",
          "role_arn": "ApplicationAccountRoleArn",
          "Name": "firehose"
        }
      },
      "portMappings": [
        {
          "hostPort": 80,
          "protocol": "tcp",
          "containerPort": 80
        }
      ],
      "image": " ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/repository-ACCOUNT_ID:latest",
      "name": "demo_container"
    },
    {
      "firelensConfiguration": {
        "type": "fluentbit"
      },
      "image": "906394416424.dkr.ecr.us-east-1.amazonaws.com/aws-for-fluent-bit:latest",
      "name": "log_router"
    }
  ]
}
  1. Registre a task definition no ECS:
aws ecs register-task-definition --cli-input-json file://container-definition.json
  1. Inicie uma nova task substituindo os valores destacados de acordo com o output do passo 3:
aws ecs run-task --cluster ECSCluster --task-definition ecs-sample-log --network-configuration 
"awsvpcConfiguration={subnets=[PublicSubnets],securityGroups=[ContainerSG],assignPublicIp=ENABLED}"
  1. Efetue algumas chamadas HTTP GET para o IP público da task (caso queira modificar a API de exemplo, edite o arquivo app.py)

Análise dos logs gerados

Com a aplicação respondendo as chamadas HTTP já é possível verificar os logs gerados na Conta de Logging, para isso execute os seguintes passos:

    1. Na Conta de Logging vá até a página do Glue e execute o Crawler criado na primeira etapa:
    2. Ao finalizar a execução do Crawler uma nova tabela será criada no catálogo de dados do Glue e agora já é possível efetuar queries no Athena. Veja a imagem abaixo demonstrando a busca por mensagens de erro com status 404:

Abaixo alguns exemplos de queries para logs que podem ser executadas utilizando SQL:

      • Todas as mensagens de log do dia 23/06/2022: SELECT * FROM “logdb”.”logging” WHERE year=’2022′ AND month=’06’ AND day=’23’
      • Busca por mensagens de log com erros 5XX: SELECT log FROM “logdb”.”logging” WHERE log LIKE ‘%code 5%’
      • Logs com erros 5XX entre um período de tempo: SELECT * FROM “logdb”.”logging” WHERE log LIKE ‘%code 5%’ AND hour BETWEEN ’17’ AND ’18’

Excluindo os recursos criados

Após os testes lembre-se de excluir os recursos criados deletando as duas stacks do CloudFormation.

Conclusão e próximos passos

Neste blog post foi demonstrado passo a passo de como criar uma solução serverless de centralização de logs de maneira Como próximo passo é possível a criação de  dashboards com o Amazon QuickSight para facilitar a análise das informações e também criar alarmes e notificações através do Amazon SNS ou AWS ChatBot possibilitando a atuação proativa.

Links adicionais

Para centralização de logs no CloudWatch recomendamos o uso desta solução: https://aws.amazon.com/solutions/implementations/centralized-logging/


Sobre os autores

Gabriel Bella Martini é formado em Ciência da Computação e especializado em Engenharia de Software. Atualmente trabalha na AWS atendendo clientes de Educação e possui experiência em diferentes projetos relacionados a Serverless e Inteligência Artificial.

 

 

 

 

Amanda Quinto é Arquiteta de Soluções da AWS no time de Setor Público com foco em Organizações sem fins lucrativos (Non-profits Organizations). Amanda já atuou em diversos projetos ajudando os times de desenvolvimento e sustentação em arquitetar sistemas resilientes e escaláveis. Formada pela FATEC-SP, é entusiasta de Devops, machine learning, e apaixonada por kombis.