AWS CloudWatch Logs — сервис для сбора и мониторинга логов с EC2, CloudTrail и Route53.
На сегодняшний день сбор логов можно выполнять двумя способами:
- старый CloudWatch Logs agent: занимается сбором логов
- новый, Unified CloudWatch Agent: объединяет в себе SSM агент и CloudWatch Logs agent, умеет собирать как метрики инстансов, так и логи. См.
Amazon CloudWatch introduces a new CloudWatch Agent with AWS Systems Manager Integration for Unified Metrics and Logs Collection ,Getting Started with CloudWatch Logs , New –Amazon CloudWatch Agent with AWS Systems Manager Integration – Unified Metrics & Log Collection for Linux & Windows ,Send Logs to CloudWatch Logs (SSM Agent) .
Unified CloudWatch Agent напоминает systemd
: попытка впихнуть невпихуемое в один сервис, такой себе «мастер на все руки». Но лично мне очень импонирует философия UNIX, и в частности концепт
Ниже рассмотрим пример сбора логов с 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:
Шаманим с Python — обновляем pip:
Устанавливаем virtualenv
:
Загружаем инсталятор:
Запускаем установку и первоначальную настройку:
Тут:
- AWS Access Key ID [None]: т.к. используем IAM роль, то не укзаываем ничего
- AWS Secret Access Key [None]: т.к. используем IAM роль, то не укзаываем ничего
- Default output format [None]: пропускаем
Единственный момент тут, на котором есть смысл остановиться немного детальнее — это формат даты-времени — Choose Log Event timestamp format.
Проверяем дату в syslog
:
May 19 13:14:20 — первый вариант, который предлагает инсталятор, как раз для syslog
— %b %d %H:%M:%S (Dec 31 23:59:59)
.
Другие примеры см. в
Файл настроек агента — /var/awslogs/etc/awslogs.conf
.
После настройки и запуска агента — в CloudWatch Logs появится Log Stream с заданным во время настройки именем:
Добавление логов
Например, для логов NGINX:
Что бы добавить ещё один файл лога в под наблюдение агента — можно запустить awslogs-agent-setup.py
с опцией --only-generate-config
:
Или просто добавить блок настроек в /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
Перезапускаем агент:
Проверяем в Logs — а там пусто… 🙂
Не сразу понял, что сервер новый, тестовый, и данных в логах NGINX ещё нет.
Делаем вызов к NGINX:
Проверяем Logs:
Настройка хранения логов
По умолчанию логи, собранные в CloudWatch Logs остаются там постоянно.
Что бы изменить срок хранения логов — кликаем на Never Expire, и выбираем период:
Уведомления
Для собираемых логов можно настроить отсылку уведомений при срабатывании определённых фильтров.
Выбираем Log group, жмём Create Metric Filter:
В Filter Pattern указываем шаблон, например — 404.
В Select Log Data to Test можем сразу протестировать срабатывание фильтра — выбрать имеющийся лог из группы, либо указать свои данные.
Доабвляем свои данные, указываем паттерн 404, проверяем:
Жмём Assign Metric, сохраняем фильтр:
Теперь можем создать аларм:
Указываем условия срабатывания аларма, и куда слать уведомление:
Подтверждаем ящик — на него будет отправлено письмо со ссылкой:
Дёргаем пару раз NGINX, что бы получить 404:

И получаем наши алармы:
Правильнее настраивать фильтры было бы так.
Шаблон:
[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 уже фильтр для кода.
Больше примеров см. в
Готово.