Skip to main content

AWS CloudWatch Logs

Conecte um log group do CloudWatch Logs ao CentralOps para coletar os logs que serviços e aplicações gravam ali: funções Lambda, tarefas ECS, API Gateway, logs exportados do RDS, appliances com o agente do CloudWatch. É a fonte "catch-all" da AWS. Para os eventos de API da própria AWS (IAM, console), use o AWS CloudTrail.

Quando usar​

  • Logs de aplicação na AWS. Erros e acessos negados de uma API que roda em Lambda ou ECS.
  • Logs de serviços gerenciados. API Gateway, logs de erro e auditoria exportados do RDS.
  • Fontes sem integração própria que já gravam no CloudWatch por agente.

Como funciona​

serviço / aplicação ──► log group ──FilterLogEvents (a cada 5 min)──► CentralOps
ItemValor
Streamevents (tipo de evento aws_cloudwatch.event)
APIFilterLogEvents em logs.<região>.amazonaws.com, ordem crescente de horário
Frequênciaa cada 5 minutos
Escopoum log group por integração, todos os log streams dele
Posição da coletahorário do evento (ms) até onde a janela foi lida; cada janela nova recua 5 minutos para pegar evento que entrou atrasado
Duplicadosdescartados pelo eventId (único por evento, garantido pela AWS)
Primeira coletaeventos da última hora
Janela por ciclono máximo 6 horas. Um atraso maior é drenado em pedaços, ciclo a ciclo
Teto por ciclo20 páginas de 1.000 eventos (20.000 eventos). Ao bater o teto, o ciclo grava o nextToken e a janela, e o seguinte continua da mesma página

A resposta do FilterLogEvents não traz log group, região, conta nem horário legível. O CentralOps acrescenta ao evento bruto os campos logGroupName, awsRegion, awsAccountId (quando informado) e eventTime (ISO 8601, convertido do timestamp em milissegundos).

Quem pode fazer o quê​

  • Administrador da plataforma: cria e edita a integração (menu Coleta -> Integrações).
  • Na AWS: criar o usuário e a policy exige permissão de IAM.

Pré-requisitos​

  • O nome exato do log group (ex.: /aws/lambda/faturamento-api) e a região dele.
  • Uma access key de usuário IAM. Assumir role, perfil de instância e credenciais temporárias com session token não são suportados.

Passo 1: Criar a credencial de leitura​

A única permissão usada é logs:FilterLogEvents no log group. Troque região, conta e nome:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LerOLogGroup",
"Effect": "Allow",
"Action": "logs:FilterLogEvents",
"Resource": "arn:aws:logs:sa-east-1:111122223333:log-group:/aws/lambda/faturamento-api:*"
}
]
}
aws iam create-user --user-name centralops-cloudwatch
aws iam put-user-policy --user-name centralops-cloudwatch \
--policy-name centralops-cloudwatch-leitura --policy-document file://policy.json
aws iam create-access-key --user-name centralops-cloudwatch

Guarde o AccessKeyId e o SecretAccessKey da saída. Para ler vários log groups, repita o Resource na policy (ou use log-group:/aws/lambda/*) e crie uma integração por log group.

Passo 2: Criar a integração no CentralOps​

  1. No menu lateral, vá em Coleta -> Integrações e adicione uma integração AWS CloudWatch Logs.

  2. Preencha:

    CampoO que informar
    Access Key IDO AccessKeyId do Passo 1.
    Secret Access KeyO SecretAccessKey do Passo 1. Fica guardado cifrado.
    Log GroupO nome exato, com as barras (ex.: /aws/lambda/faturamento-api). Sem curinga.
    Região AWSA região do log group (ex.: sa-east-1).
    Account IDOpcional. Só preenche cloud.account.uid no evento normalizado, porque a API não devolve a conta.
  3. Clique em testar a conexão. O teste faz um FilterLogEvents de 1 evento na última hora do log group. Ele valida de uma vez a credencial, a permissão e a existência do log group. Responde Conexão OK — acesso ao log group validado. ou Falha ao consultar o log group: <tipo do erro>.

  4. Salve. A coleta começa no próximo ciclo (até 5 minutos).

O que é coletado​

Cada evento do log group vira um evento normalizado em OCSF 1.8, classe Base Event (0), porque o conteúdo de um log group é livre. O evento original fica no raw.

Se o campo message for um JSON, o CentralOps o lê e aproveita alguns campos comuns. Se não for, o evento segue normalizado só com a mensagem em texto.

Campo OCSFOrigem
time, metadata.original_timeeventTime (vem do timestamp do CloudWatch)
messagemessage, inteira
severity_id / severitylevel ou severity dentro do JSON: trace/debug/info/notice → 1; warn/warning → 3; error/err → 4; critical/crit/alert → 5; fatal/emerg/emergency → 6. Sem o campo: 1
metadata.uideventId
metadata.log_name, unmapped.log_grouplogGroupName
metadata.correlation_uid, unmapped.log_streamlogStreamName
cloud.region / cloud.account.uidregião do formulário / Account ID do formulário
unmapped.operationeventName, operation ou action do JSON
unmapped.user_nameuser, userName ou userIdentity.userName do JSON
unmapped.src_ipsourceIPAddress, srcAddr, client_ip ou clientIp do JSON
unmapped.error_code / unmapped.error_messageerrorCode ou error / errorMessage do JSON
unmapped.status, unmapped.user_agent, unmapped.user_uidstatus, userAgent, userId ou userIdentity.principalId do JSON
observablesusuário e IP acima, quando existem

Para uma fonte específica (um formato de aplicação seu), crie um mapeamento próprio em Normaliza -> Mapeamentos que coloque os campos na classe OCSF certa. Veja Normalização.

Exemplo​

Evento bruto (dados sintéticos), já com os campos que o CentralOps acrescenta:

{
"eventId": "38451234567890123456789012345678901234567890123456789012",
"timestamp": 1792503727000,
"ingestionTime": 1792503728113,
"logStreamName": "2026/10/20/[$LATEST]0a1b2c3d4e5f",
"message": "{\"level\":\"ERROR\",\"operation\":\"DeleteInvoice\",\"user\":\"ana.souza@example.com\",\"clientIp\":\"198.51.100.17\",\"status\":403,\"errorMessage\":\"forbidden\"}",
"logGroupName": "/aws/lambda/faturamento-api",
"awsRegion": "sa-east-1",
"awsAccountId": "111122223333",
"eventTime": "2026-10-20T13:42:07.000Z"
}

Evento normalizado:

{
"normalized": {
"class_uid": 0,
"class_name": "Base Event",
"category_uid": 0,
"category_name": "Uncategorized",
"activity_id": 0,
"activity_name": "Unknown",
"type_uid": 0,
"time": 1792503727000,
"metadata": {
"original_time": "2026-10-20T13:42:07.000Z",
"version": "1.8.0",
"product": {
"name": "CloudWatch Logs",
"vendor_name": "AWS"
},
"uid": "38451234567890123456789012345678901234567890123456789012",
"log_name": "/aws/lambda/faturamento-api",
"log_provider": "AWS CloudWatch Logs",
"correlation_uid": "2026/10/20/[$LATEST]0a1b2c3d4e5f"
},
"severity_id": 4,
"severity": "High",
"message": "{\"level\":\"ERROR\",\"operation\":\"DeleteInvoice\",\"user\":\"ana.souza@example.com\",\"clientIp\":\"198.51.100.17\",\"status\":403,\"errorMessage\":\"forbidden\"}",
"cloud": {
"provider": "AWS",
"region": "sa-east-1",
"account": {
"uid": "111122223333"
}
},
"unmapped": {
"log_group": "/aws/lambda/faturamento-api",
"log_stream": "2026/10/20/[$LATEST]0a1b2c3d4e5f",
"operation": "DeleteInvoice",
"error_code": null,
"error_message": "forbidden",
"user_name": "ana.souza@example.com",
"user_uid": null,
"src_ip": "198.51.100.17",
"user_agent": null,
"status": 403
},
"observables": [
{
"name": "actor_user",
"type": "User Name",
"type_id": 4,
"value": "ana.souza@example.com"
},
{
"name": "src_ip",
"type": "IP Address",
"type_id": 2,
"value": "198.51.100.17"
}
]
}
}

Solução de problemas​

Falha ao consultar o log group: ResourceNotFoundException. O log group não existe naquela região. Confira o nome (com barra inicial) e a região: aws logs describe-log-groups --log-group-name-prefix /aws/lambda/faturamento --region sa-east-1.

Falha ao consultar o log group: AccessDeniedException. Falta logs:FilterLogEvents no ARN desse log group, ou a policy aponta para outra região ou conta.

O teste passa, mas nada chega. O log group pode não ter recebido eventos desde que a integração foi criada. Confira com aws logs filter-log-events --log-group-name /aws/lambda/faturamento-api --start-time $(( ($(date +%s) - 3600) * 1000 )) --limit 5 --region sa-east-1.

"Backlog" em Saúde do Pipeline. O ciclo leu 20.000 eventos e sobrou fila. Se acontece sempre, o log group gera mais do que cerca de 4.000 eventos por minuto, que é o que a coleta drena de forma contínua.

Erros de throttling (ThrottlingException). A cota do FilterLogEvents é por conta e região, e é dividida com qualquer outra ferramenta que leia logs na mesma conta. O ciclo que falha é repetido no seguinte, a partir da posição salva.

Limitações conhecidas​

  • Um log group por integração, pelo nome exato. Não há curinga nem lista.
  • Só access key estática.
  • Classe genérica. Todo evento sai como Base Event (0); os campos extraídos do JSON ficam em unmapped, não em atributos OCSF de classe.
  • Volume alto acumula atraso. O teto de 20.000 eventos por ciclo de 5 minutos limita a vazão. Log groups como VPC Flow Logs de uma VPC movimentada passam disso.
  • Recoleta histórica (backfill) não respeita o período pedido. O coletor começa da janela padrão (última hora), não do início do período escolhido.