Upload
alex-popov
View
543
Download
7
Embed Size (px)
Citation preview
Трассировка событий при логировании
Попов Александр(@alexgpg), CTI(cti.ru)
Зачем мы пишем логи?
• Отладка.• Пишем прошедшие события. Кроме логов ничего нет. Если что-
то не записали, то новой информации уже не будет.
Проблемы анализа логов
• Смешивание разных событий в одном логе.• В распределенной системе одно событие обрабатывается на
нескольких машинах и записи об одном событии попадают в разные логи.
• Для анализа логов нужно постоянно держать в голове контекст. Постоянно перемещаться между исходным кодом и логами.
Антипаттерны логирования1. Записи-близнецы
• Не понять как различить и к чему относятся. Приходится понимать по косвенным признакам, по дополнительной информации.
2014-06-14 01:19:06 INFO: Request to API: user: [email protected] 2014-06-14 01:19:06 INFO: Request to API: user: [email protected] 2014-06-14 01:19:06 INFO: Request to API: user: [email protected]
Антипаттерны логирования2. Анонимный лог
• Запись в логе в которой нет имени подсистемы.• Кто написал?• Доходит до ctrl+c ctrl+f по исходному коду, чтобы понять что
это за подсистема
Антипаттерны логирования3. Отсутствие цели
• Error request to api.something.com with code 500.• А что хотели-то?
Антипаттерны логирования4. Литературные логи
• Request from server1.api.com from user ad12 with product id 18• Текст не поискать по приложению• В отдельные нужные данные еще прицелится надо
Антипаттерны логирования5. Забытый отладочный вывод
• puts user => logger.info user => logger.info «user: #{user}»
Антипаттерны логирования6. Object.inspect
• Одновременно нечитаем человеком и машиной.
#<User:0x00000001240990 @created_at=2014-06-13 23:13:01 +0400, @name="Petr", @organization=#<Organization:0x00000001240a08 @name="umbrella", @billing_id="122233">, @email="[email protected]", @external_id="5757585">
Антипаттерны логирования7. Exception без стектрейса
• Error Timeout reached.• Ээээ...а где оно возникло и где обработалось?
Трассировка событий
• Способ пометить всю цепочку сообщений одного события, чтобы отличать от остальных.
• В начале обработки события генерируется уникальный ID и записывается в каждом сообщении в лог.
• Этот ID передается через все обработчики, все слои приложения и машины участвующие в обработке.
Трассировка событий
Трассировка событийВ коде(log4r)
• Используем Nested Diagnostic Context (NDC)• Используем Nested Diagnostic Context (NDC)• Используем Nested Diagnostic Context (NDC)• Используем Nested Diagnostic Context (NDC)• Используем Nested Diagnostic Context (NDC)
# Logging initlogger = Log4r::Logger.new 'common'outputer = Log4r::Outputter.stdoutoutputer.formatter = Log4r::PatternFormatter.new(pattern: '%d %l: [%x] %m ')logger.add outputer# New requestLog4r::NDC.push uuid()logger.info 'Incoming request'#...logger.info 'In progress'#...logger.error 'Bad params
Трассировка событийВ коде(ext_logging)
ev = UserEvent.new ext_logger.info ev, 'Incoming request'ext_logger.info ev, 'In progress'ext_logger.error ev, 'Bad params'
Трассировка событийВ логе
2014-06-13 21:43:50 INFO: [9cc6fdc1] Incoming request 2014-06-13 21:43:50 INFO: [afc8ba03] In progress 2014-06-13 21:43:50 INFO: [9cc6fdc1] In progress 2014-06-13 21:43:50 ERROR: [9cc6fdc1] Bad params
Трассировка событийГенерация ID события
• Искусственная — просто генерируем новый уникальный ID.• Естественная — берем ID уже существующий в бизнес-логике.
Например, ID транзакции из внешней системы.
Трассировка событийИерархическая структура событий
• Обработка события может состоять из нескольких подзадач.• Интересно наблюдать каждую из подзадач раздельно и
различать события в них друг от друга. • При этом есть главное инициирующее событие — корень дерева
событий.
Трассировка событийЧто еще записать в лог
• Короткое имя события(reg_user, create_conf). Тогда из записи будет понятна конечная цель
• Пользователя-инициатора события. Логин, email, ip.• Подсистему или класс.
I, [2014-06-04T03:48:09.422777 #17400] INFO -- : [b9f64570] (add_resource){[email protected]} <ResourcesService> | Add limit |=> {"company":"umbrella", "limit":"12"}
Трассировка событийПреимущества
• Разные события различимы.• Много контекста пишется сразу. • grep позволяет фильтровать по различным признакам.
I, [2014-06-04T03:48:09.422777 #17400] INFO -- : [b9f64570] (add_resource){[email protected]} <ResourcesService> | Add limit |=> {"company":"umbrella", "limit":"12"}
Хранимые события
• Хранятся в базе.• Поиск средствами БД по множеству параметров(SQL, MongoDB
query).• Можно показывать прямо в интерфейсе приложения.• Перезапуск обработки события в случае неудачи.
Хранимые событияСхема БД
• Уникальный ID• Короткое имя• Инициатор: ID или имя пользователя• Время создания• Статус: IN_POGRESS, DONE, FAILED• Дополнительные данные в свободном формате(json, hstore)
Хранимые событияТрассировка событий в логах
• Используем ID сохраненного события как ID для трассировки.
ext_logging
• Гем для поддержки трассировки событий в логах.
• Трассировка событий.
• Иерархия событий.
• Пишет класс откуда был вызван логер.
• https://bitbucket.org/alexgpg/ext_logging• Пока в разработке.
Что почитать или посмотреть?
• Nail B. Harrison «Patterns for Logging Diagnostic Messages»• Zipkin - distributed tracing system http://twitter.github.io/zipkin/• http://www.infoq.com/presentations/Zipkin• ddima Дядя Дима - Логи
ddima.livejournal.com/64901.html - часть первая ddima.livejournal.com/65086.html - часть вторая ddima.livejournal.com/65668.html - часть третья ddima.livejournal.com/66497.html - часть четвертая
Выводы
• Трассировка событий — простой полезный паттерн, который экономит время анализа логов.
• События можно хранить в БД. Это дает возможности для гибкого задания параметров поиска по ним.
Спасибо
Вопросы?