2008-11-06 2 views
18

Недавно я нашел оператор журнала в своих кодах кода проектов, который говорит «вот я с параметром поиска ==> =========== 11/30/2008 === 1 ==== 00:00 «Какие руководящие принципы вы придерживаетесь для написания хороших заявлений о регистрации

Какие руководящие принципы вы придерживаетесь для написания хороших сообщений журнала в приложении?

ответ

12

Этот оператор `log 'больше похож на инструкцию трассировки.

Logging: показать нормальные события и ошибки

Трассировка: показать путь выполнения, а также все регистрации событий

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

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

Многие ответы здесь сосредоточены на полях, которые вы включили бы в сообщение журнала, но я бы сказал, что уровень размещения и ведения журнала вызовов журнала более важен.Если вы используете log4net, вы сможете включать/исключать штамп даты по умолчанию через конфигурационные файлы, но вы не сможете размещать или удалять записи журналов без перекомпиляции, поэтому имеет смысл серьезно подумать о том, куда они идут. Помимо стандартных полей, таких как метка времени и идентификатор потока, и т. Д., Вы хотите узнать имя класса и метода, из которого был сделан вызов. Log4net et al. Заботится о имени класса уже, если вы перейдете к своей лучшей практике именования вашего регистратора после того типа, с которым вы связаны. Помимо этого, я обычно включаю имя метода. Это особенно необходимо для отслеживания, но я включаю его во все мои сообщения журнала.

Logging:

Вы хотите знать достаточно информации о том, какие действия собирается быть выполнены, чтобы вернуться назад и копаться, если что-то пойдет не так. Хорошими кандидатами являются идентификаторы сообщений, адреса электронной почты, то, что однозначно идентифицирует рабочий элемент. Такое сообщение должно появиться, как только будут доступны такие данные, чтобы при чтении через файл журнала вы увидите что-то вроде «попытки сделать x с y», а затем, если мы увидим исключение, мы знаем, какой рабочий элемент нам нужно посмотреть, чтобы понять, почему мы потерпели неудачу.

Ошибки регистрации должны быть соединены с сообщением журнала попыток, так что сообщение об ошибке имеет смысл в контексте при чтении журнала. Это означает мысль о структуре обработки исключений. Если вы используете .net, и вы хотите только регистрировать исключение, а не обрабатывать его, вы хотите повторно удалить исключение, а не новое, поэтому просто «бросайте», а не «бросайте e», где «e» ваш экземпляр исключения. Посмотрите это, если это не имеет смысла.

Трассировка:

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

Performance:

Для выполнения строки, используйте методы '* Формат', если вы используете log4net или что-то подобное. Это внутренне будет использовать StringBuilder, чтобы вы не платили неизменную строчную штрафную сумму все время. Как правило, хотя ключ состоит в том, чтобы иметь возможность отключить трассировку для производительности и иметь протоколирование достаточно кратким, чтобы оставаться включенным, даже если сообщение журнала дорого. Когда это правильно сделано, их должно быть недостаточно, чтобы быть проблемой.

12

Самая полезная часть в операторе журнала (за исключением, может быть, даты & времени, конечно) - уникальный идентификатор. Все наши записи в журнале начинаются с MSG-xxxxx, где xxxxx - уникальное целое число. Этот тег MSG-xxxxx всегда жестко закодирован в источнике, никогда в файле ресурсов, поэтому его легко найти. Это также очень простой ключ поиска в документации.

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

MSG-12345 пытался открыть «myfile.txt», возвращается код ошибки «123 - файл не найденный".

Это также помогает при попытке извлечь информацию из журнала с использованием некоторого регулярного выражения.

+0

Это хорошо, потому что вы можете поместить MSG-12345 в wiki – 2008-11-06 23:39:56

+0

В некоторых контекстах может быть полезным идентификатор процесса или PID (а иногда и идентификатор потока или TID). Но Стефан дает отличный совет. – 2008-11-07 06:36:31

5

Не выполняйте конкатенацию строк в операторах регистрации, по крайней мере, для отладочных инструкций.

Одно приложение Java, над которым я работал некоторое время назад, имел мрачную производительность. Таким образом, мы взломали профайлер, чтобы увидеть, где были узкие места. Оказалось, что в основном это связано с операциями конкатенации String, возникающими при сборке заявлений о регистрации уровня DEBUG, которые произошли ВСЕ ВРЕМЯ во внутри вложенных внутренних петель и т. Д. (Да, и подумать, что они добавлены в первую очередь, чтобы выяснить, почему производительность была настолько плоха !)

не делают этого

LOGGER.debug("The variable was " + myVariable + " and we are doing " + foo); 

Вместо это сделать

if (LOGGER.isDebugEnabled()) { 
    LOGGER.debug("put your debug statement here " + foo + " and " + bar); 
} 
4

в моих журналах, мне нужно DAT e и время, процесс, который создает журналы, и PID. Нет ничего хуже, чем смотреть на журналы и задаваться вопросом, пришли ли они пять минут назад или остались ли они 5 лет назад до ваших изменений. Дата и время важны.

Когда я сообщаю об ошибках, я кратко излагаю, что было вызвано, что произошло, и какие коды ошибок вернулись. Если это errno, я также сообщаю об ошибке (errno). Я читаю это, чтобы найти проблему, и обычно я нахожусь в спешке, чтобы найти проблему. Я не хочу смотреть на вещи. Я хочу, чтобы он рассказал мне, что случилось, и я предпочитаю многословную бесполезность. Если я отлаживаю, и часто даже, когда я этого не делаю, я буду записывать все данные, такие как оператор SQL или запись низкого уровня, ключи, все, что поможет мне найти проблему как можно скорее.

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

1

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

В больших проектах, где вы хотите получать сообщения от клиентов, сталкивающихся с проблемами, также помогает, если вы можете контролировать, какие части вашего приложения будут регистрироваться; например, если есть проблемы с чтением информации пользователя AD, вы можете добавить «AD_LOGGING = EVERYTHING» и получить подробную информацию о регистрации на этом, не видя информацию журнала из всех остальных разделов программы.

2

Мы используем «двумерное» ведение журнала, то есть ведение журнала по отдельному модулю и внутри этого уровня. Это дает нам реальный контроль при попытке отладить проблемы с клиентами.

Каждая запись в журнале имеет уникальный идентификатор плюс дата плюс время плюс модуль плюс уровень отладки. Идентификатор отражается (если необходимо) в сообщении об ошибке/ошибке, отображаемом пользователю. Поэтому, если пользователи регистрируют инцидент, мы можем быстро поднять этот раздел журнала и посмотреть, что произошло вокруг этого момента.

Сообщения уровня отладки не используют такие общие понятия, как «Недопустимый вход», мы регистрируем фактические значения, вызвавшие проблему. Если это поле имеет отношения к другим полям, мы также регистрируем их.

4

Есть 5 аспектов, которые являются важными для меня (начиная с менее важно):

  1. Включить временную метку в записи журнала
  2. Обеспечить возможность отфильтровать менее важные, «спам» записи. Хороших, старых квадратных скобок теги должно быть достаточно для grep. Было бы неплохо, если бы некоторые из них были сгенерированы автоматически - в зависимости от типа журнала (сообщение, предупреждение, утверждение и т. Д.) И, при необходимости, уровень важности сообщения (спам, нормальный, высокий, критический). Добавление дополнительных тегов сужения контекста вручную также рекомендуется ИМО.
  3. Сделать функции журнала/макросы такими же простыми в использовании, насколько это возможно.
  4. Сброс выходных буферов немедленно.
  5. Предоставьте возможность мгновенного и однозначного определения места генерации записи в журнале (имя исходного файла + номер строки). Это может быть сложно на некоторых языках, но очень часто зная, какое именно утверждение является неудачным, означает немедленное исправление ошибки. Кроме того, вы не теряете время для добавления идентификаторов места регистрации вручную (например, «SomeClass :: SomeMethod: Message»)
Смежные вопросы