пятница, 22 августа 2014 г.

Вопрос. Стоит ли писать о выводе стека исключений в лог приложения?

Стоит ли писать о выводе стека исключений в лог приложения?

Или gunsmoker (http://www.gunsmoker.ru/) об этом уже всё исчерпывающе написал?

Вообще тема "косвенного сбора диагностики" от "конечных пользователей" интересна или нет?

Disclaimer. Конечных пользователей я не зря взял в кавычки. Так как у реальных коммерческих пользователей - какой бы то ни было "сбор данных" без их ведома и подписанного договора - это вообще говоря - подсудное дело.

Посему тема-то - касается не только "вывода стека", о и того "как что-то собрать" никого не ущемляя в его правах приватности.

Про "вывод стека" - я написать могу, а вот про "приватность" - с удовольствием других бы послушал.

У реально конечного пользователя - даже дамп стека и данных снять - это "дело подсудное", т.к. в этом дампе легко могут оказаться "приватные данные", например те же логины.

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

Но я наверное "всех запутал" своей шизофренией про "приватность". Про дамп стека надо писать? Или все уже в курсе?

11 комментариев:

  1. «Про дамп стека надо писать?»
    -- Конечно пишите.
    Мы давно и успешно применяем для этой цели немного поправленный JCLDebug.
    Но конечно интересно почитать об альтернативных путях.
    Некоторые, насколько мне известно, предпочитают EurekaLog, мне сталкиваться с этим не приходилось...
    Да и вообще, решения для ведения log-файлов, его формат (не факт, что plain text лучший выбор, как альтернативу можно рассмотреть БД SQLite) - интересные и слабораскрытые темы...

    ОтветитьУдалить
    Ответы
    1. Мы тоже JclDebug используем + хранение логов в бинарном кастомном формате (не знаю чем был обусловлен такой выбор - такой код достался в наследство). И простой текстовый формат мне видится более привлекательным, чем необходимость использовать отдельные тулзы для просмотра.

      Удалить
    2. «И простой текстовый формат мне видится более привлекательным, чем необходимость использовать отдельные тулзы для просмотра.»
      -- До тех пор, пока лог не становится огромным. Особенно, если там стек вызовов приводить.
      Далее:
      * На диске он начинает занимать заметное место, что становится критичным при запросе логов у пользователя - файл размером в сотни мегабайт непросто передать по сети.
      * Найти что-либо интересующее в таком логе - тоже проблема.
      * Если ограничить размер такого текстового лога в runtime - алгоритм получается непростым и небыстрым, иногда приходится разбирать этот лог, используя знание его структуры.
      * В некоторых случаях критичным становится конкурентная запись в единый лог не только из разных нитей, но и из разных процессов, запускаемых в контексте основного приложения.
      * При желании архивировать логи на сервер, с текстовым форматом работать неудобно.
      * Написать приложение, выгружающее лог из БД в текст - задача на несколько минут на Python.
      Решить обратную задачу - загрузить лог в БД для последующего анализа - в общем случае нетривиально, хотя понятно, что есть такие решения.

      Удалить
    3. Log Rotation же, с архивированием. Впрочем, тоже надо реализовывать как-то.
      Хотя да. Серверный лог и клиентский лог - у всех своя специфика.
      У меня в клиентской программе - новый лог создаётся в момент запуска. Хранятся логи несколько дней. А серверной части нет - так что и проблемы нет. =)

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

      Надо будет поискать есть ли для делфей что-то подобное java-вскому logback-у.

      Удалить
    4. «Log Rotation же, с архивированием. Впрочем, тоже надо реализовывать как-то.»
      -- Уже реализовали. Я написал, чем мне это не нравится: это не быстрый алгоритм в случае больших логов, кроме того, там возникают дополнительные сложности при конкуретном доступе к нему.
      Решение, основанное на БД лишено этих недостатков. И проще и быстрее.

      «Хотя да. Серверный лог и клиентский лог - у всех своя специфика.
      У меня в клиентской программе - новый лог создаётся в момент запуска. Хранятся логи несколько дней.»
      -- Да я, в основном, о клиентской части и говорю.
      Лог-файл в многозвенной архитектуре может быстро становиться очень большим, особенно в ситуации, когда в него заносятся диагностические сообщения, да и стек вызовов исключений, возможных при нормальной работе, также вносит существенную часть по объёму.

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

      «Надо будет поискать есть ли для делфей что-то подобное java-вскому logback-у.»
      -- Вот эта вещь произвела приятное впечатление...

      Удалить
    5. >Решение, основанное на БД лишено этих недостатков. И проще и быстрее.
      +
      > А информацию из логов очень полезно анализировать не только в плане поиска ошибки п программе, но и выявления системных причин неэффективной работы программы.

      И тут я перехожу от контекста "мы пишем лог, чтобы потом разобраться что пошло не так", к контексту "сначала мы решим для чего нам нужны логи, а потом решим что туда писать и как это хранить". А потом подумаем как это будем обрабатывать.

      И плавно эволюционируем от простейшего - пишем лог в файл рядом с программой через StringList из главного потока, к пишем в файл из разных потоков. А потом дадим возможность писать в лог из разных процессов. А потом начнём писать в БД. Возможно выбросим наш код для записи в лог и заменим на хорошую библиотеку (а ля hotlog, log4d, log4delphi).
      Потом сообразим что БД тоже может быть недоступна. Сделаем отдельный сервис для управления логами. Или возьмём готовый CodeSite или SmartInspect.
      Поработав так какое-то время заметим, что читать логи из БД не очень удобно, и попробуем прикрутить к ней какую-нибудь читалку с парсером и простейшей аналитикой. А может даже попытаемся всять готовый инструмент и попытаемся прикрутить к этому делу какой-нибудь LogStash или Kibana. А если денег много, а времени нет - то даже купим лицензию на Splunk.
      Но скорее всего остановимся на каком-нибудь этапе, приспособимся к тому что есть и будем потихонечку это улучшать считая своё решение вполне оптимальным.

      Вот как-то так я всё это вижу.

      p.s. А для выявления закономерностей периодичности загруженности сервера, вполне можно выдавать наружу какие-нибудь метрики и использовать отдельный сервис для мониторинга. Тот же Zabbix, например. Впрочем, это уже совсем другая песня. =)

      Удалить
    6. Ваше направление мыслей мне понятно, но по-моему, Вы смотрите слишком далеко.
      Сам стремлюсь к постепенному, эволюционному движению.
      Иными словами, сначала начинаем хранить лог в БД и получаем выгоду от этого.
      "Читалка" таких логов в нашем случае будет "из коробки", для остальных в качестве такой "читалки" на первое время вполне можно применить Far Manager.
      Если логи хранятся в БД (SQLite представляется хорошим решением) сразу появляется мысса возможностей по анализу информации из логов, чему может способствовать классификация исключений и построение полнотекстового индекса по логу при необходимости.
      В CodeInsight и подобных решениях пока потребности не испытывали.
      Вероятно, наличие мощного скрипт-движка (вроде Python) позволит дёшево решить значительную часть задач, возникающих в контексте анализа данных из логов. Их фильтрацию, например.

      «p.s. А для выявления закономерностей периодичности загруженности сервера, вполне можно выдавать наружу какие-нибудь метрики и использовать отдельный сервис для мониторинга. Тот же Zabbix, например. Впрочем, это уже совсем другая песня. =)»
      -- Да, другая :-)
      Но чтобы эту "песню заводить" IMHO нужно создать инфраструктуру для её исполнения.
      Элементом такой инфраструктуры может стать автоматизированное сохранение логов с клиентов на сервере БД для последующего анализа.
      Если на стороне клиента логи хранятся в БД, эта задача не представляется слишком сложной.

      Удалить
    7. > но по-моему, Вы смотрите слишком далеко.
      А у меня просто было в жизни 2 разных опыта. Первый - как я уже описывал - с локальным хранением клиентских логов рядом с программой в бинарном виде. А второй опыт - это когда уже была настроена инфраструктура где примерно на 70 машинах крутились разные серверные приложения, которые тоже писали логи - генерируя от сотни мегов до гига логов в сутки. И вот в связи со вторым вариантом как раз и пришлось немножечко поисследовать - а как бы всё это дело хранить так, чтобы было удобнее просматривать, фильтровать и искать. И там не вставало вопроса о том, чтобы брать скрипт-движок, или писать что-то своё. Ибо слишком дорого и долго выйдет. А в качестве кандидатов рассматривался тот же Splunk (который на таких объёмах тоже оказался весьма недешёвым), и различные Open Source решения основанные на каком-нибудь Elastic Search - та же связка Logstash + Kibana выглядет вполне себе аппетитно.

      Опыты конечно разные - клиентские логи и серверные логи - это 2 большие разницы. И если во втором случае сетевая инфраструктура уже в принципе есть, то в первом - её скорей всего нет.

      Удалить
    8. Ну... У нас тоже есть серверный лог, создаваемый серверным Java-приложением.
      И он тоже довольно большой. Для его обработки как раз использовали Python: нужно было выбирать запросы, приходившие от определённого клиента. Это несложная задача.
      Хотя для просмотра этих логов используются как раз те решения, на которые указали Вы, или их аналоги.
      Вообще же, я не рассматриваю ситуацию, когда требуется анализ логов множества различных приложений от различных поставщиков. Наверное, она имеет смысл, но это всё же не то, с чем мне регулярно приходится иметь дело.
      Для меня актуальны задачи накопления и анализа логов приложений, разрабатываемых нашей фирмой.
      Собственно, в этом контексте были мои предыдущие сообщения.

      Удалить
  2. > Так как у реальных коммерческих пользователей - какой бы то ни было "сбор данных" без их ведома и подписанного договора - это вообще говоря - подсудное дело.

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

    ОтветитьУдалить
  3. Ну и я использую jclDebug. Правда тоже с правками :-) В общем - Америку я опять не открыл :-)

    ОтветитьУдалить