AWS / CloudWatch — ETAPA 1 / Enviando logs de sua aplicação para o CloudWatch
Ola Gente
Gerenciar log de aplicações pode parecer simples no começo, 10 mil arquivos de log por dia, depois vai crescendo e acumulando uma quantidade de informação enorme e se torna trabalhoso gerenciar tantas informações.
Para nos ajudar com isto existe o CloudWatch.
Em nosso projeto de teste teremos o seguinte cenário:
- Uma aplicação rodando em PHP com sistema de login
- Iremos querer monitorar os logins (Sucesso/Falhas)
- Iremos agrupar todas estas informações no CloudWatch
- Após isto criaremos métricas que irao nos mostrar, em forma de gráfico, a quantidade de sucessos/falhas por hora
- Iremos criar um alarme para caso a quantidade de falhas ultrapasse 30 falhas em 1 hora seja disparado um aviso para nó
- Iremos conectar os logs do CloudWatch com o serviço ElasticSearch para permitir consultar os logs
Neste primeiro tutorial iremos aprender como postar informações de log no CloudWatch.
Antes de começarmos precisamos criar um Grupo e um Fluxo, dentro deste Fluxo iremos inserir todos os logs deste site.
Exemplo:
Grupo: MeusSites
Fluxo: site1.com.br
1. Acesse o painel da AWS e entre em https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#
2. Clique em “Logs”

3. Clique em “Create Log Group”
4. Preencha o nome do grupo como “TesteGrupo1” e confirme a ação

5. Clique no recém criado grupo

6. Clique em “Create Log Stream”
7. Preencha com o nome “TesteFluxo1” e confirme a ação

Temos o Grupo/Fluxo Pronto! Iremos criar um usuário (E credenciais) para permitir que seja enviados logs através de nossa aplicação.
Este usuário precisa possuir as duas permissões abaixo:
- CloudWatch Logs -> DescribeLogStreams
- CloudWatch Logs -> putLogEvents
1. Acesse https://console.aws.amazon.com/iam/home?region=us-east-1
2. Clique em “Users”
3. Clique em “Add User”
4. Preencha o nome “TesteUsuario1”
5. Selecione “Programmatic Access” (Isto ira gerar as credenciais de acesso a API)
6. Clique em “Next: Permissions”
7. Não altere as permissões neste momento, apenas clique em “Next: Review”
8. Clique em “Create User”
9. Clique em “Show” na coluna “Secret Access Key” e ANOTE o “Access Key ID” e o “Secret Access Key”

10. Clique em “Close”
11. Clique no Usuário recém criado
12. Clique em “Add Inline Policy”

13. Clique em “Json”

14. Preencha com o json abaixo, este json concede as duas permissões que iremos utilizar:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:DescribeLogStreams",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
15. Clique em “Review Policy”
16. No campo “Name” preencha com “TesteUsuario1_Permissoes”
17. Clique em “Create Policy”
Ótimo, agora temos o usuário com permissão de enviar informações para o log.
Vamos para o PHP!
Aqui vou considerar que você já tem a SDK da AWS em sua aplicação, mas caso não tenha, inclua: https://github.com/aws/aws-sdk-php
Vamos entender como funciona o envio de logs para a AWS.
Os envios dos logs são feitos através do método putLogEvents, caso já tenha sido enviado algo, é necessário enviar o ID do último registro junto, para isto iremos utilizar o DescribeLogStreams
Primeiro iremos definir algumas variáveis com os dados:
<?
$AccessKey = "XXXXXXXXX";
$SecretAccessKey = "XXXXXXXX";
$LogGroupName = "TesteGrupo1";
$LogStreamName = "TesteFluxo1";
$NextSequenceToken = "";
?>
Agora iremos iniciar o objeto responsável por acesso ao CloudWatch:
<?
try {
$credentials = new Aws\Credentials\Credentials($AccessKey, $SecretAccessKey);
$client = new Aws\CloudWatchLogs\CloudWatchLogsClient([
'version' => 'latest',
'region' => "us-east-1",
'credentials' => $credentials
]);
} catch (Aws\CloudWatchLogs\Exception\CloudWatchLogsException $e) {
die($e->getMessage());
}
?>
Esta próxima etapa é interessante, iremos consultar o FLUXO para checar o último ID gravado (Se tiver um ID gravado claro!)
<?
try {
$result = $client->DescribeLogStreams([
'logGroupName' => $LogGroupName,
'logStreamName' => $LogStreamName
]);
if( count($result["logStreams"]) > 0 )
{
$NextSequenceToken = $result["logStreams"][0]["uploadSequenceToken"];
}
} catch (Aws\CloudWatchLogs\Exception\CloudWatchLogsException $e) {
die($e->getMessage());
}
?>
E vamos a diversão, enviar informações ao log:
<?
try {
if( $NextSequenceToken == "" )
{
$result = $client->putLogEvents([
'logGroupName' => $LogGroupName,
'logStreamName' => $LogStreamName,
'logEvents' => [
[
'message' => json_encode(array("Acao" => "Login", "Resultado" => "Falha", "ClienteCodigo" => 1, "ClienteNome" => "Luiz")),
'timestamp' => round(microtime(true) * 1000),
]
]
]);
}else{
$result = $client->putLogEvents([
'logGroupName' => $LogGroupName,
'logStreamName' => $LogStreamName,
'logEvents' => [
[
'message' => json_encode(array("Acao" => "Login", "Resultado" => "Falha", "ClienteCodigo" => 1, "ClienteNome" => "Luiz")),
'timestamp' => round(microtime(true) * 1000),
]
],
'sequenceToken' => $NextSequenceToken
]);
}
} catch (AwsException $e) {
die($e->getMessage());
}
?>
Note que todo json fica dentro da variável “logEvents -> message” e que a codificação é UTF-8!
PRONTO!
Segue script completo:
<?
$AccessKey = "XXXXXXXXX";
$SecretAccessKey = "XXXXXXXX";
$LogGroupName = "TesteGrupo1";
$LogStreamName = "TesteFluxo1";
$NextSequenceToken = "";
try {
$credentials = new Aws\Credentials\Credentials($AccessKey, $SecretAccessKey);
$client = new Aws\CloudWatchLogs\CloudWatchLogsClient([
'version' => 'latest',
'region' => "us-east-1",
'credentials' => $credentials
]);
} catch (Aws\CloudWatchLogs\Exception\CloudWatchLogsException $e) {
die($e->getMessage());
}
try {
$result = $client->DescribeLogStreams([
'logGroupName' => $LogGroupName,
'logStreamName' => $LogStreamName
]);
if( count($result["logStreams"]) > 0 )
{
$NextSequenceToken = $result["logStreams"][0]["uploadSequenceToken"];
}
} catch (Aws\CloudWatchLogs\Exception\CloudWatchLogsException $e) {
die($e->getMessage());
}
try {
if( $NextSequenceToken == "" )
{
$result = $client->putLogEvents([
'logGroupName' => $LogGroupName,
'logStreamName' => $LogStreamName,
'logEvents' => [
[
'message' => json_encode(array("Acao" => "Login", "Resultado" => "Falha", "ClienteCodigo" => 1, "ClienteNome" => "Luiz")),
'timestamp' => round(microtime(true) * 1000),
]
]
]);
}else{
$result = $client->putLogEvents([
'logGroupName' => $LogGroupName,
'logStreamName' => $LogStreamName,
'logEvents' => [
[
'message' => json_encode(array("Acao" => "Login", "Resultado" => "Falha", "ClienteCodigo" => 1, "ClienteNome" => "Luiz")),
'timestamp' => round(microtime(true) * 1000),
]
],
'sequenceToken' => $NextSequenceToken
]);
}
} catch (AwsException $e) {
die($e->getMessage());
}
?>
Veja em nosso cloudwatch:

No próximo tutorial iremos criar métricas com estes dados!
Por hoje é isto, queridos desenvolvedores! 👩💼
Até logo! 👋
Leia também
AWS SES: recebendo e-mails e mandando pra um webhook
Como configurar o recebimento de e-mails no Amazon SES e fazer cada mensagem que chega cair num webhook seu, passando pelo SNS.
Node.js: autenticando um remetente no AWS SES
Como verificar um e-mail no AWS SES pelo SDK do Node.js e enviar mensagens usando esse endereco como remetente autenticado.
Aws Lambda — IP Fixo no Tráfego de Saída
Passo a passo para atribuir um IP público fixo a uma função Lambda na AWS