суббота, 26 сентября 2015 г.

Немного мыслей про логгирование в приложениях на C#

Предположим вы решили писать какую-то программу, небольшую утилиту. И даже прикрутили к ней лог. И даже не стали писать свой велосипед, а взяли какую-нибудь отлаженную и хорошую библиотеку (в моём случае NLog http://nlog-project.org ). Так вот в первые строчки лога после запуска вбивайте "ВРЕМЯ-Название-ВЕРСИЮ-ОСНОВНЫЕ НАСТРОЙКИ".

Объясню почему -

  • Название - чтобы когда вам просто тупо скинули файл лога (ещё и переименовав его как-нибудь "Лог.ткст", то вы из первой строчки могли вытащить хоть какую то инфу от чего этот лог )))
  • Время - чтобы понимать, что лог актуальный, а то бывает вообще программа не работает и лог от старой версии. А вы смотрите в него и в нём всё нормально.
  • Версию - похоже на предыдущий пункт, но немного другое. Бывает, что человек, которому вы делаете программу и выкатили новый релиз, на вас ругается, что новый функционал не работает. А в логах чисто. И пользователь утверждает, что таки да - "ОБНОВИЛ, Мамой клянусь". Так вот. Бывает, что не обновляет. Бывает сам закосячишь и в апдейторе забудешь предварительно закрыть предварительно программу если открыта (а винда не даст вам просто взять и перезаписать, запущенный файл). А косяки прут. Дополнительно можно вставлять версию операционнки, особенно если есть "зависимый" функционал (то есть работает только выше 7, XP мимо и прочее такое). Сюда же можно всякое про браузеры, антивирусы и прочее что влияет на работу программы. 
  • Основные настройки - все особо смысла нет (разве что при дотошной отладке, обычно если место хранение настроек едино и прочиталась одна, то и все остальные тоже. Но не факт) А для чего? Чтобы убедиться, что программа считывает настройки и не пытается работать с настройками по умолчанию. И не подключается к удалённому серверу БД не потому, что "файрволл, нет клиенсткой библиотеки и прочее блядство", а просто потому, что пробует подключиться на дефолтный локалхост

Также очень хорошая идея это писать несколько уровней логов, к примеру для деббага выводить целую кучу, причём и в файл, и на консоль, и куда-нибудь в БД. А для релиза только ошибки, фатальные и прочие ерроры. Причём неплохо бы для релизной ветки сразу же выкидывать окошко с предложением отправить лог разрабу.

Ну и пункт выходящий из предыдущего пункт - пусть логгирование дебаг уровня будет вместо комментариев :) Тоже достаточно интересный финт ИМХО.

Дополнительно нужно не забывать про права записи для логов. И пробовать запускать программу от ограниченного (в правах) пользователя. Так как если программа ставится в Program Files и логи пишутся в папку с программой, то можно поймать трабл когда логи не будут писаться. А учитывая, что вывод в лог часто в самом начале программы, то может получится, что будет ошибка на запись и программа просто будет вылетать при запуске не оставляя логов. Но при этом во время разработки глюков не будет никаких.

Добавлено 12.10.2015:
Ещё нужно давать возможность совсем отключать логи. Это может потребоваться в разных ситуациях, начиная от запрета на запись из соображений безопасности, кончая увеличением ресурса SSD или увеличением скорости работы.

Про скорость работы программы - некоторые программисты делают избыточные логи (каюсь, порой грешен) и забывают делать замеры производительности. Для примера приведу одну из ситуаций: была программа, задача которой было очень много считать, причём очень тяжелые формулы, так вот - запись на медленный хард во время процесса выполняемого быстрым процессором, давала постоянные задержки выполнения (грубо говоря 5мс считает, 30мс пишет лог), что в реальной работе совершенно лишнее.

Ограничение размера логов - ОЧЕНЬ желательно реализовывать систему "обрезки" логов, либо по размеру, либо по дате. Иначе рано или поздно вы просто забьёте пользователю всё свободное место на диске. Да и работать с лог-файлами размером в пару десятков-сотен гигабайт очень неудобно