Журнал информации о лучших практиках - PullRequest
4 голосов
/ 07 ноября 2010

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

Не могли бы вы предоставить наилучшую практику или руководство по записи информации журнала?

Кстати: мы используем log4Net. У вас есть предложения по альтернативной библиотеке?

Спасибо.

Ответы [ 4 ]

7 голосов
/ 07 ноября 2010

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

  • Включите дату и время.Если ваше приложение распределено по часовым поясам, включите индикатор часового пояса.Это устранит путаницу, если все будут точно знать, какое время 03:11:04 находится в их часовом поясе.
  • Включите уровень серьезности ведения журнала.
  • Включите некоторое указание модуля или класса, который вызвалlog массаж в сообщении журнала.
  • Если возможно, поощряйте разработчиков включать в сообщения конкретную информацию: например, «Файл поврежден», гораздо менее полезен, чем «Файл поврежден:» C: \ foo\ bar.dat "'
  • Если возможно, попросите разработчиков включить какой-либо идентификатор сеанса или транзакции в сообщение об ошибке.Удобно иметь возможность фильтровать журналы для сообщений от транзакции, в которой произошла ошибка, и игнорировать все транзакции, которые были в порядке.
  • Часто хорошей идеей является включение кода ошибки в сообщения журнала дляошибки.

Второй совет, который дал @Oded, чтобы сообщения были аккуратными.Для рутинных вещей, даты и времени, уровня журнала, кода ошибки я бы попытался отформатировать их, чтобы они были фиксированной ширины, и поместил их в начало.Это значительно упрощает сканирование журналов.

Что касается хороших руководств по форматированию сообщений журналов, единственное, что я натолкнулся на это, - глава 17 книги «Выпусти это!»: http://www.pragprog.com/titles/mnee/release-it AМногие из приведенных выше советов основаны на этом.

2 голосов
/ 08 ноября 2010

@ corriganjc имеет много хороших предложений.

Я бы добавил некоторые особенности: рассмотрите возможность регистрации сообщений с использованием UTC, если это возможно.С одной стороны, может быть раздражающим смотреть на сообщения, генерируемые в «вашем» часовом поясе, а затем запоминать нужное количество, чтобы компенсировать их, чтобы интерпретировать их «правильно».С другой стороны, все ваши сообщения журнала будут отсортированы по времени / дате без дальнейшей интерпретации.(Если у вас есть сообщения, зарегистрированные в двух часовых поясах, и вы зарегистрировали их, используя «местное» время, вы не можете сортировать их, пока не перенесете их в общий часовой пояс).

Используйте GlobalContext, ThreadContext иОбъекты LogicalThreadContext для добавления дополнительного контекста в ваши сообщения.Предложение занести в журнал что-то вроде «идентификатора сеанса» или «идентификатора транзакции» является хорошим и, вероятно, может быть наиболее эффективно реализовано с использованием объектов «контекста», а не путем явного добавления этих значений к фактическим сайтам регистрации вызовов.Вы можете установить контекст один раз и, с добавлением опции форматирования, зарегистрировать этот контекст с любым сообщением.

Если вы используете объект контекста, рассмотрите возможность создания «стандартных» имен значений или даже определения строковых констант, которые могутразработчики могут ссылаться на них, чтобы они не делали опечаток при попытке добавить свой контекст:

//Context value names
public static class DiagnosticContextValueNames
{
  public static string TransactionId = "transactionid";
  public static string SessionId = "sessionid";
}

//In your code
log4net.ThreadContext.Properties[DiagnosticContextValueNames.TransactionId] = GetTransactionId();
log4net.ThreadContext.Properties[DiagnosticContextValueNames.SessionId] = GetSessionId();

//Somewhere later on...
logger.Info("hello");  // this message can be tagged with the transaction id and session id if you use the appropriate formatting options

Вы можете даже рассмотреть методы расширения в GlobalContext.Properties, ThreadContext.Properties и т. д., чтобы помочь руководству разработчиковдля правильной установки значений контекста:

public static class LoggingExtensions
{
  public static void SetTransactionId(this ThreadContextProperties props, string trans)
  {
    props["TransactionId"] = trans;

    // Or, using constants as defined above...
    props[ThreadContextValueNames.TransactionId] = trans;
  }
}


// In your code...
log4net.ThreadContext.Properties.SetTransactionId(GetTransactionId());

// As compared to this:
log4net.ThreadContext.Properties["transactionid"] = GetTransactionId();

Если вы перенесете или унаследуете от регистратора log4net, вы можете автоматически добавить некоторую контекстную информацию, что избавит ваших разработчиков от этой нагрузки.Существует правильный способ обернуть или унаследовать log4net logger, но это не ракетостроение.Ключ должен передать log4net тип вашего упакованного логгера.Ответ cfeduke в этого поста дает один способ обернуть регистратор log4net.

Вы можете последовать его примеру, но реализовать все вызовы журналирования в терминах метода "ILogger.Log".Внутри «Журнала» вы можете добавить свойства, которые вы хотите для всех ваших сообщений журнала:

// This approach requires more effort than simply populating the context properties "normally", and
// is probably overkill for most situations.  However, it can prove useful if you are able
// to have access to the context information that you want to log from within the Log method
// of the logger.
public void Log(type loggerBoundaryDeclaringType, LogLevel level, object message, object exception)
{
  log4net.ThreadContext.Properties["transactionid"] = GetTransactionId();
  log4net.ThreadContext.Properties["sessionid"] = GetSessionId();
  _logger.Log(loggerBoundaryDeclaringType, level, message, exception);
}

Что касается других платформ журналирования, вы можете взглянуть на NLog .Новая версия была выпущена как бета-версия недавно.Он имеет много возможностей, аналогичных log4net.

Вы также можете рассмотреть старый добрый System.Diagnostics.TraceSource.Если вы идете по этому пути, загляните в Ukadc.Diagnostics на codeplex.Это библиотека дополнений для System.Diagnostics, которая предоставляет широкие возможности форматирования сообщений (аналогично тому, что вы можете делать с log4net и NLog).Одна хорошая вещь об Ukadc.Diagnostics - это то, что это зависимость только от конфигурации.Вам не нужно брать исходную или ссылочную зависимость, чтобы использовать ее.

2 голосов
/ 07 ноября 2010

ELMAH - очень хорошая библиотека журналирования и неплохая альтернатива log4net.

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

1 голос
/ 28 ноября 2010
> ... we're using log4Net. Do you have any suggestion on alternative library? 

Вы можете использовать common.logging (http://netcommon.sourceforge.net), который представляет собой крошечную оболочку регистрации, которая работает вместе с

  • log4net
  • Nlog
  • Ведение журнала корпоративной библиотеки

Это усложняет настройку ведения журнала, поскольку вам необходимо настроить, какой механизм ведения журнала использовать, а также настроить механизм ведения журнала.

API-интерфейс для логирования основан на log4net-api

...