AWS: CloudWatch logs — сбор и мониторинг логов

Автор: | 05/19/2018
 

AWS CloudWatch Logs — сервис для сбора и мониторинга логов с EC2, CloudTrail и Route53.

На сегодняшний день сбор логов можно выполнять двумя способами:

  1. старый CloudWatch Logs agent: занимается сбором логов
  2. новый, Unified CloudWatch Agent: объединяет в себе SSM агент и CloudWatch Logs agent, умеет собирать как метрики инстансов, так и логи. См. Amazon CloudWatch introduces a new CloudWatch Agent with AWS Systems Manager Integration for Unified Metrics and Logs CollectionGetting Started with CloudWatch Logs, New – Amazon CloudWatch Agent with AWS Systems Manager Integration – Unified Metrics & Log Collection for Linux & WindowsSend Logs to CloudWatch Logs (SSM Agent).

Unified CloudWatch Agent напоминает systemd: попытка впихнуть невпихуемое в один сервис, такой себе «мастер на все руки». Но лично мне очень импонирует философия UNIX, и в частности концепт Do One Thing and Do It Well.

Ниже рассмотрим пример сбора логов с NGINX на AWS EC2, используя «старый» CloudWatch Logs agent.

Документация — тут>>>.

IAM роль

Сначала требуется добавить IAM роль с правами на запись в CloudWatch, которую далее подключим к EC2.

Переходим в IAM > Roles, жмём Create Role, оставляем значение Allows AWS services to perform actions on your behalf, выбираем EC2, жмём Next: Permissions:

Добавляем политику CloudWatchAgentServerPolicy:

Сохраняем роль:

Подключаем политику к инстансу с NGINX, переходим в Instances, правой кнопкой — Instance Settings > Attach/Replace IAM roles:

Выбираем политику, жмём Apply, готово.

Установка агента

Устанавливаем на Ubuntu 16.04:

root@ip-172-31-32-24:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.4 LTS

Шаманим с Python — обновляем pip:

root@ip-172-31-32-24:~# pip install ---upgrade pip

Устанавливаем virtualenv:

root@ip-172-31-32-24:~# pip3 install virtualenv

Загружаем инсталятор:

root@ip-172-31-32-24:~# curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O

Запускаем установку и первоначальную настройку:

root@ip-172-31-32-24:~# python3 ./awslogs-agent-setup.py --region eu-west-1
Launching interactive setup of CloudWatch Logs agent ...
Step 1 of 5: Installing pip ...libyaml-dev does not exist in system DONE
Step 2 of 5: Downloading the latest CloudWatch Logs agent bits ... DONE
Step 3 of 5: Configuring AWS CLI ...
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [eu-west-1]:
Default output format [None]:
Step 4 of 5: Configuring the CloudWatch Logs Agent ...
Path of log file to upload [/var/log/syslog]:
Destination Log Group name [/var/log/syslog]:
Choose Log Stream name:
1. Use EC2 instance id.
2. Use hostname.
3. Custom.
Enter choice [1]: 3
Enter Log Stream name [None]: nginx_cf_logs_example
Choose Log Event timestamp format:
1. %b %d %H:%M:%S    (Dec 31 23:59:59)
2. %d/%b/%Y:%H:%M:%S (10/Oct/2000:13:55:36)
3. %Y-%m-%d %H:%M:%S (2008-09-08 11:52:54)
4. Custom
Enter choice [1]: 1
Choose initial position of upload:
1. From start of file.
2. From end of file.
Enter choice [1]: 1
More log files to configure? [Y]: n
Step 5 of 5: Setting up agent as a daemon ...DONE
------------------------------------------------------
- Configuration file successfully saved at: /var/awslogs/etc/awslogs.conf
- You can begin accessing new log events after a few moments at https://console.aws.amazon.com/cloudwatch/home?region=eu-west-1#logs:
- You can use 'sudo service awslogs start|stop|status|restart' to control the daemon.
- To see diagnostic information for the CloudWatch Logs Agent, see /var/log/awslogs.log
- You can rerun interactive setup using 'sudo python ./awslogs-agent-setup.py --region eu-west-1 --only-generate-config'
------------------------------------------------------

Тут:

  • AWS Access Key ID [None]: т.к. используем IAM роль, то не укзаываем ничего
  • AWS Secret Access Key [None]: т.к. используем IAM роль, то не укзаываем ничего
  • Default output format [None]: пропускаем

Единственный момент тут, на котором есть смысл остановиться немного детальнее — это формат даты-времени — Choose Log Event timestamp format.

Проверяем дату в syslog:

root@ip-172-31-32-24:~# tail -1 /var/log/syslog
May 19 13:14:20 ip-172-31-32-24 amazon-ssm-agent[30899]: #011status code: 400, request id: 35ddcf06-e9a9-4b31-a887-f6f32e5eba2

May 19 13:14:20 — первый вариант, который предлагает инсталятор, как раз для syslog%b %d %H:%M:%S    (Dec 31 23:59:59).

Другие примеры см. в How to: Set-up and configure AWS CloudWatch LogsChoose Log Event timestamp format.

Файл настроек агента — /var/awslogs/etc/awslogs.conf.

После настройки и запуска агента — в CloudWatch Logs появится Log Stream с заданным во время настройки именем:

Добавление логов

Например, для логов NGINX:

root@ip-172-31-32-24:~# ls -l /var/log/nginx/
total 0
-rw-r------ 1 www-data adm 0 May 19 11:31 access.log
-rw-r------ 1 www-data adm 0 May 19 11:31 error.log

Что бы добавить ещё один файл лога в под наблюдение агента — можно запустить awslogs-agent-setup.py с опцией --only-generate-config:

root@ip-172-31-32-24:~# python3 ./awslogs-agent-setup.py --region eu-west-1 --only-generate-config
Launching interactive setup of CloudWatch Logs agent ...
Skipping downloading and installation of agent bits.Step 3 of 5: Configuring AWS CLI ...
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [eu-west-1]:
Default output format [None]:
Step 4 of 5: Configuring the CloudWatch Logs Agent ...
Path of log file to upload [/var/log/syslog]: /var/log/nginx/access.log
Destination Log Group name [/var/log/nginx/access.log]:
Choose Log Stream name:
1. Use EC2 instance id.
2. Use hostname.
3. Custom.
Enter choice [1]: 3
Enter Log Stream name [None]: nginx_cf_logs_example
Choose Log Event timestamp format:
1. %b %d %H:%M:%S    (Dec 31 23:59:59)
2. %d/%b/%Y:%H:%M:%S (10/Oct/2000:13:55:36)
3. %Y-%m-%d %H:%M:%S (2008-09-08 11:52:54)
4. Custom
Enter choice [1]: 3
Choose initial position of upload:
1. From start of file.
2. From end of file.
Enter choice [1]:
More log files to configure? [Y]:
Path of log file to upload [/var/log/syslog]: /var/log/nginx/error.log
Destination Log Group name [/var/log/nginx/error.log]:
Choose Log Stream name:
1. Use EC2 instance id.
2. Use hostname.
3. Custom.
Enter choice [1]: 3
Enter Log Stream name [None]: nginx_cf_logs_example
Choose Log Event timestamp format:
1. %b %d %H:%M:%S    (Dec 31 23:59:59)
2. %d/%b/%Y:%H:%M:%S (10/Oct/2000:13:55:36)
3. %Y-%m-%d %H:%M:%S (2008-09-08 11:52:54)
4. Custom
Enter choice [1]: 3
Choose initial position of upload:
1. From start of file.
2. From end of file.
Enter choice [1]: 1
More log files to configure? [Y]: n
Step 5 of 5: Setting up agent as a daemon ...DONE

Или просто добавить блок настроек в /var/awslogs/etc/awslogs.conf руками:

...
[/var/log/nginx/error.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/nginx/error.log
buffer_duration = 5000
log_stream_name = nginx_cf_logs_example
initial_position = start_of_file
log_group_name = /var/log/nginx/error.log

[/var/log/nginx/access.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/nginx/access.log
buffer_duration = 5000
log_stream_name = nginx_cf_logs_example
initial_position = start_of_file
log_group_name = /var/log/nginx/access.log

Перезапускаем агент:

root@ip-172-31-32-24:~# service awslogs restart

Проверяем в Logs — а там пусто… 🙂

Не сразу понял, что сервер новый, тестовый, и данных в логах NGINX ещё нет.

Делаем вызов к NGINX:

root@ip-172-31-32-24:~# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

Проверяем Logs:

Настройка хранения логов

По умолчанию логи, собранные в CloudWatch Logs остаются там постоянно.

Что бы изменить срок хранения логов — кликаем на Never Expire, и выбираем период:

Уведомления

Для собираемых логов можно настроить отсылку уведомений при срабатывании определённых фильтров.

Выбираем Log group, жмём Create Metric Filter:

В Filter Pattern указываем шаблон, например — 404.

В Select Log Data to Test можем сразу протестировать срабатывание фильтра — выбрать имеющийся лог из группы, либо указать свои данные.

Доабвляем свои данные, указываем паттерн 404, проверяем:

Жмём Assign Metric, сохраняем фильтр:

Теперь можем создать аларм:

Указываем условия срабатывания аларма, и куда слать уведомление:

Подтверждаем ящик — на него будет отправлено письмо со ссылкой:

Дёргаем пару раз NGINX, что бы получить 404:

root@ip-172-31-32-24:~# curl localhost/nofile
<html>
<head><title>404 Not Found</title></head>
...

И получаем наши алармы:

Правильнее настраивать фильтры было бы так.

Шаблон:

[ip, dash, user, timestamp, request, statusCode=404, size]

Дефолтный лог NGINX:

log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

Т.е. в паттерне фильтра считаем первое поле — IP, потом пробел и т.д., и в поле statusCode уже фильтр для кода.

Больше примеров см. в Filter and Pattern Syntax.

Готово.

Ссылки по теме

Centralized Log Management with AWS CloudWatch

A simple way to manage log messages from containers: CloudWatch Logs

How to: Set-up and configure AWS CloudWatch Logs

How to use CloudWatch to generate alerts from logs?