Обычно библиотеки логгирования предлагают из коробки сразу несколько "уровней" важности, с которыми Вы можете записывать сообщения. В документации к ним можно найти рекомендации - как лучше этими уровнями пользоваться, примерно такие:
Info
: все ожидаемые события, учет которых
запланирован.
Warning
: неожиданные/подозрительные события - иначе
говоря аномалии, после которых еще возможно продолжение работы
приложения.
Error
: событие, после которого невозможно дальнейшее
выполнение программы.
Fatal
: событие, требующее по-настоящему немедленного
вмешательства.
Проблема в том, что это все не совсем работает без некоторых дополнительных соглашений и уточнений. Именно о них я и хотел бы поговорить ниже.
"Продолжить работу"
Трактовать возможно продолжить работу можно очень по разному.
Скажем, на экране пользователя можно настроить любимый цвет рамки
вокруг экрана: пусть будет розовый. Если по каким-то причинам
хранилище, где мы держим эти настройки цвета было недоступно и мы
не можем отобразить этот цвет - можно ли это считать как возможно
продолжить или это катастрофа? К сожалению, я еще ни разу не
встречал хорошего универсального формального критерия, чтобы четко
можно было разделять "катастрофа-терпимо". А раз не можешь
остановить - значит нужно направить. Потому я предлагаю
инвертировать споры об это неправильный уровень: если в коде
написано, что отсутствие цвета - это Error
- значит
программист Вам говорит, что этот цвет чертовски важен в этом
домене - возможно, именно этот цвет сигнализирует, что сейчас надо
продавать акции на миллионы долларов, и наоборот. Соответственно,
чтение кода немного меняется: когда видите место, где из-за
какой-то на Ваш взгляд ерунды прерывается выполнение, вопрос,
который должен возникать автору, Почему ты считаешь, что это так
важно? вместо Истинно тебе говорю - ты программируешь
неправильно!.
Схожая инверсия может помочь в вечных спорах на тему это
исключительная ситуация или нет. Опять же, все довольно просто.
Важна не техническая составляющая: нет соединения к базе - это
исключение, а серверу прислали неправильный id
- так
это ожидаемо. Важно то,чья это будет головная больи как ее
можно избежать или хотя бы минимизировать урон. Чьи планы на вечер
пятницы пойдут к черту из-за того, что это сломалось? Если Вашим
сервисом пользуются приложения, которые вне Вашего контроля, то Вам
действительно плевать на то, что они присылают некорректные
id
и у них там что-то идет не так. Если Ваше
приложение - это инструмент для управления базой данный - наподобие
Sql Server Magement Studio - очевидно, что отсутствие доступа к
базе - не Ваша печаль. А если Вашим сервисом пользуются приложения,
за которые Вы же и в ответе - то это Ваши неприятности в конечном
счете. Вопрос лишь в том, как и когда Вы об этом узнаете - быстро
из сработавшей сигнализации или от звонка злого как черт владельца
бизнеса, которому Вы пишете софт. А также вопрос в том, как дешево,
надежно и сердито эту сигнализацию наладить.
"Error"
Давайте представим себе экран, где есть кнопка Открыть и текстовое поле. Эта кнопка по замыслу должна открыть Вам какой-то полезный функционал, а в текстовом поле предполагается ввести имя и фамилию. После нажатия на кнопку принципиально возможны два сценария: приложение либо крэшится либо нет. Если же мы были удачливы и оно не упало, у нас опять два варианта: мы получили желанный экран или мы получили сообщение об ошибке вместо него. Сообщение об ошибке в свою очередь можно принципиально разделить еще на два класса: может ли пользователь сам исправить ситуацию в рамках программы или нет - имеется ввиду корректирование своего ввода, а не обратиться к Вашему системному администратору.
Жаль, что нет комикса о том, как программист ловит льва в пустыне - он здесь был бы очень уместенНа практике сообщение вида Обратитесь к администратору это
просто подслащенные крэш. Да, несомненно это лучше, чем убить весь
процесс со всеми пользовательскими данными, но от этого оно не
перестает фактически блокировать работу. В тоже время ошибка может
быть сообщением о неправильных с точки зрения программы действиях,
а именно надо было ввести имя и фамилию Джон Иванов, а человек ввел
просто Джон и валидатору это не нравится. К чему это все? Что
вообще у нас тут речь идет о 3-х достаточно разных сущностях, но
при том на каждую из них можно сослаться как Error, что
вызывает изрядную путаницу. Крэш приложения - это несомненно
уровень Error
в нашей системе определений, но это
очень важный Error
.
Ошибка валидации имя-фамилии - это несомненно уровень
Info
- мы ждем, что пользователь будет норовить
записать все что угодно, а мы - пресекать это. Ну и записывать все
те разы, когда пользователь был неправ. Но от этого ошибки не
перестают бесить людей, которые их видят. То, что напрямую связано
с людьми и их UX - важно; и неплохо бы присматривать за этим, не
допускать, чтобы сообщения об этом тонули в километрах унылых
Info
записей Пользователь такой-то залогинился. Иными
словами, чтобы устранить путаницу, хочется иметь уровни
Error+
и Info+
.
Я предвижу восклицания Так погодите, ведь крэш приложения - это
недопустимо! Надо сразу действовать! Это Fatal
уровень!" На это я неспеша прикурю воображаемую сигарету, затянусь
и задумчиво отвечу: Ну всех ведь все равно не спасти...". Ладно, я
не курю, но, думаю, образ понятен. Появление сообщения
Fatal
должно быть эквивалентом запуска тревоги
воздушной угрозы, когда в офисе разработки врубается сирена и это
жуткое красное аварийное освещение. Вот честно, Вы именно так
реагируете на то, что у кого-то из бухгалтерии на экране, который
раз в сто лет запускают, упало приложение? Вполне может быть
нормально, что у Вас сейчас даже и нет подобной ситуации,
где уровень Fatal
- согласно такой системы определений
- нужен. Так вот трюк в том, чтобы не блокировать возможность
добавить обработку такой потенциальной ситуации в будущем, забивая
сейчас Fatal
уровень сообщениями, которым
важностьError+
в самый раз.
Таким образом, мы приходим к тому, что в действительности неплохо бы иметь уровни вида
Info
Info+
Warning
Error
Error+
Fatal
Плюсовые уровни можно легко организовать в Вашей любимой
библиотеке логгирования расширив ее существующие методы
Error/Info
, которые бы просто унифицировано добавляли
какой-то хэштэг в обычные сообщения, скажем
#IMPORTANT.
Что ж - это все, что я хотел сказать об ошибках и их логгировании. Буду рад, если этот текст добавит разработчикам больше взаимопонимания и уменьшит споры о том, как "правильно".