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:
- 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
- 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}/
- 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.
- 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:
- Execução do CloudFormation na conta de Logging;
- Criação de uma aplicação de exemplo na conta de Aplicação;
- Análise dos logs gerados.
Pré-requisitos
Para seguir o passo a passo veja os seguintes pré-requisitos:
- Duas contas AWS (Aplicação e Logging)
- Clonar o repositório da solução
- AWS CLI
- Docker CLI
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:
- 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
- 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).
- 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 post “Under the hood: FireLens for Amazon ECS Tasks”.
Execute os passos abaixo:
- 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.
- 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);
- Anote todos os valores encontrados na aba de output após a execução da stack;
- 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
- 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"
}
]
}
- Registre a task definition no ECS:
aws ecs register-task-definition --cli-input-json file://container-definition.json
- 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}"
- 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:
-
- Na Conta de Logging vá até a página do Glue e execute o Crawler criado na primeira etapa:
- 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://thinkwithwp.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.