Как писать лог-файлы, которые экономят время

Сначала позвольте немного поразглагольствовать: программа, поддержкой которой я занимаюсь по работе, содержит много милых особенностей. “Произошла ошибка”  —  не то, что достойно такого описания. Сообщения об ошибке не просто начинаются этой фразой. Они ей исчерпываются.

Или как насчет: “Информация об ошибке находится в логах сервера”, но в сообщении нет никаких указаний, какой сервер на самом деле выдал исключение?

Эта статья  —  о том, как писать логи и сообщения об ошибках, которые не выглядят настолько плохо.

А это точно нужно?

Большая часть этой статьи посвящена предоставлению дополнительной информации. Но сначала  —  только на мгновение  —  посмотрим на некоторые сообщения в логах, которые можно безопасно вырезать. Почему? Скажем так: читая лог-файл в километр длиной, вы будете благодарны за все, что не отнимает у вас мыслительные ресурсы.

  • Записи вида “Все хорошо” для каждой итерации цикла. Пока я знаю, что программа запустилась нормально и, возможно, сейчас войдет в этот цикл, меня волнуют только ошибки.
  • Записи журналов производительности, когда я не тестирую производительность.
  • Каждый шаг функции/вычисления. Не нужно регистрировать “а” и “в”, когда вы уже регистрируете “а+в=с”.

В большинстве случаев лучше избыток информации, чем недостаток, но все же стоит учитывать обстоятельства, чтобы не перегнуть палку.

Пожалуйста, сообщите, в чем ошибка

Большинство исключений, с которыми мы сталкиваемся в обычной жизни, не обрабатываются явно, а это означает, что мы часто получаем трассировку стека, которая точно сообщает нам, что произошло, где и когда. Тут все в порядке. Это не особенно читабельно, но, по крайней мере, есть возможность проследить источник.

Если, однако, вы фиксировали исключение через блок catch, чтобы затем вывести на консоль: “Что-то не работает”, даже не печатая в лог-файл, просто не делайте этого. Если вы пишете пользовательский обработчик исключений, то потратьте одну лишнюю минуту на объяснение, в чем заключается ошибка. Это неправильная запись в базе данных, например, или неправильно отформатированное имя? Хорошо, теперь не нужно клонировать репозиторий и отлаживать все самому. Можно просто немедленно исправить нужную запись в базе данных.

Пожалуйста, сообщите, где конкретно возникла ошибка

Это моя самая большая болевая точка при исправлении ошибок: мы получаем ежедневный мониторинг сообщений об ошибках, но самое хорошо написанное сообщение не приведет далеко, если я даже не знаю, откуда оно взялось. Просто выведите что-нибудь вроде:

fatal error: invalid cast at serverIWouldLikeToSlaughter

И это уже гораздо лучше.

Предоставьте дополнительные параметры, с которыми можно работать

В продолжение предыдущего примера: вероятно, когда вы пишете сообщение об ошибке, у вас под рукой уже есть вся информация, так почему бы не дать ее мне? Просто выведите идентификатор клиента, номер счета, адрес электронной почты, который вы не можете десериализовать.

Fatal error: Invalid cast type Boolean to Integer numberOfSwearwords at serverIWouldLikeToSlaughter

Перегружайте только конкретные исключения

Если вам хочется создать исключение для неправильных типов данных или что-то в этом роде, вам надо подключиться к InvalidCastException или аналогично  —  но не к Exeption. Таким образом, самая распространенная ошибка будет сопровождаться большим сообщением с говорящим именем и описанием. Но когда происходит что-то необычное, вы все равно регистрируете полную трассировку стека, и она не теряется.

Try{thisOrthat();}
Catch castEx as InvalidCastException{
  log.error("detailed description of error");
}
Catch ex as Exception{
  log.error(ex.stacktrace);
}

Взглянем на примеры таких лог-файлов

Вот лишь некоторые случайно выбранные образцы того, что я бы счел полезными записями в журнале логов  —  вещи, которые значительно облегчают понимание того, где возникла ошибка и как ее исправить:

-загружается server1 application4 
-соединение с otherServer на порту 1337 - успешно
-проверка базы данных; соединение с databaseServer5 Ошибка 400:Of course it doesn’t work, your credentials are outdated but not even the database admins have a clue what the new one are. Конечно, ничего не работает, ваши учетные данные устарели, но даже администраторы базы данных не имеют понятия, какими должны быть новые.
-программа завершила работу в 00:34 pm, 1234 файлов обработано успешно, 23 неуспешно, 45 пропущено
-Нет доступа к файлу asdfadsfa.txt поскольку файл открыт другим процессом
-ошибка обновления таблицы базы данных tb_xyz, максимальная длина столбца 50 превышена в столбце "name"
-обработка текстового поля HTML не удалась, это часто вызвано проблемами форматирования на стороне базы данных. Проверьте у администраторов базы данных, было ли получено из БД следующее значение: <a\">helloworld\"</a>

Каждое из этих сообщений об ошибках сэкономило бы полчаса просто на поиске источника и сути ошибки  —  по сравнению с теми сообщениями, которые либо не описывают ошибку вообще, либо описывают неэффективным способом.

Заключение

Минута затраченного времени может сэкономить вам часы в будущем.

Надеюсь, статья была для вас полезной!

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи: keypressingmonkey, “How to Write Log Files That Save You Hours of Time”

Предыдущая статья3 признака того, что ваш ИИ-проект обречен
Следующая статьяИспользование конкурентности при создании API в Go