Каковы лучшие практики для включения ведения журнала с использованием log4net? - PullRequest
19 голосов
/ 14 декабря 2009

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

Следовательно, существует ли в любом случае набор руководящих указаний относительно того, что регистрировать, чтобы получить разумную цену / выгоду от ?

Таким образом:

Какие виды журналирования следует добавить к приложению, которое было бы полезно позже?

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

-

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

Ответы [ 9 ]

8 голосов
/ 15 декабря 2009

Следует иметь в виду, что, хотя ваша конфигурация будет обрабатывать журналирование на разных уровнях, вы можете вызывать большие издержки при вызовах журналов. Например:

// some kind of loop
// do some operations
Logger.LogDebug(myObject.GetXmlRepresentation());
// end loop

Это, очевидно, будет регистрировать объект только в том случае, если у вас есть регистратор, прослушивающий журналы DEBUG, однако вызов для создания объекта XML будет выполняться независимо от уровня ведения журнала и может привести к значительным замедлениям.


Правильное решение будет:

// some kind of loop
// do some operations
if (Logger.IsDebug)
{
    Logger.LogDebug(myObject.GetXmlRepresentation());
}
// end loop
6 голосов
/ 14 декабря 2009

Я нашел эту статью очень полезной: http://blog.codinghorror.com/the-problem-with-logging/

В частности, я думаю, что минималистский подход - действительно путь. В прошлом я слишком много пытался войти в систему, но это раздувает код

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

5 голосов
/ 15 декабря 2009

Мой любимый источник информации для такого рода вопросов - Release It - книга от прагматичных парней. Настоятельно рекомендуется.

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

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

2 голосов
/ 14 декабря 2009

В общем с логированием я добавляю логирование в следующем порядке:

  1. Функция входа / выхода
  2. Основные логические шаги внутри функции
  3. Подробное ведение журнала для всех промежуточных расчетов

Очевидно, что я редко дохожу до последнего, первый тривиально сделать, если вы бросите свою собственную обертку для log4net и используете шаблон удаления, и, возможно, немного магии отражения.

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

Третий, как правило (для меня в любом случае), выполняется только в тех разделах кода, в которых наблюдается регрессия, или они особенно важны.

Я реализовал базовый объект-обертку для log4net, который предоставляет мне возможности прямой регистрации, а также объект контекста, который можно использовать с IDisposable, чтобы обернуть логику «входа / выхода» в хороший удобный пакет.

1 голос
/ 10 декабря 2010

Ведение журнала не простая задача, но, по моему опыту, все журналы должны быть доступны для поиска ответственных лиц. Полезная цель для ошибок - электронная почта непосредственно (и в некоторых случаях SMS). Но в конце концов все данные журналов должны быть доступны для поиска в базе данных с удобным пользовательским интерфейсом.

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

  • Критические ошибки: должны быть доступны немедленно по электронной почте / смс
  • Будущие выпуски: ежедневные / еженедельные письма
  • Отладочная информация ==> ежедневное / еженедельное электронное письмо с уведомлением о том, сколько отладочной информации создается с прошлого раза.

Содержание отладки может быть записано в базу данных по-разному, но нам нужно оценить производительность. Большой объем данных не следует записывать в базу данных в «производственном режиме». Это должно быть сделано на ежедневной / еженедельной основе. Лучший способ - создать локальный файл (например, XML или простой текст) и поместить этот файл в базу данных в часы обслуживания (ночью). Должна быть предусмотрена возможность запуска / остановки сеанса отладки и запись отладочной информации в базу данных только после завершения сеанса отладки.

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

Ясно одно ... ВСЕ ошибки / исключения должны быть где-то зарегистрированы. Нет ничего более раздражающего, чем потерянные сообщения об ошибках:)

Счастливая отладка!

1 голос
/ 15 декабря 2009

Какие виды журналирования следует добавить в приложение, которое будет полезно позже?

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

Для исключений CLR или сторонних разработчиков регистрируйте Exception.ToString (), а не просто сообщение, в противном случае вы пропускаете трассировку полного стека (при условии, что программисты не проглатывают исключения или не перебрасывают внутреннее исключение без sans)

Сосредоточьтесь на деталях отладки в тех областях, где вы либо знаете, либо подозреваете, что у вас будут проблемы (просто спросите QA или техподдержку, где искать; -)

Если вы следуете принципу надежности , то вы можете захотеть регистрировать INFO или WARN, когда игнорируете или изменяете входные данные или ожидаемое поведение. Это может быть полезно, если ваша служба WCF начинает получать неожиданные (но анализируемые) входные данные.

Чтобы убедиться, что ваше приложение работает хорошо, не отправляйте / не устанавливайте его с включенным по умолчанию протоколированием уровня DEBUG, возможно, вам подойдут ERROR или WARN.

Я не согласен с последней частью принятого ответа, потому что log4net обладает потрясающими возможностями фильтрации; при условии, что ваши программисты понимают, что ведение журналов обходится дорого (согласно ответу CK), и они (и QA и Техническая поддержка) знают о фильтрах, и что настройка всего в DEBUG - плохая идея. Если вы регистрируете на уровне DEBUG большой граф объектов, XML-документ, результат db и т. Д., Оберните его в некоторый код, который уменьшает затраты:

if (log.IsDebugEnabled)
{
    log.DebugFormat("Loaded in {0} ms {1}", timer.ElapsedMilliseconds, dataSet.GetXml());
}

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

Если вы следуете такому подходу и хотите получить (довольно небольшое) снижение производительности, вот один из способов, который использует трассировку стека для создания объектов ILog для любого класса и обеспечения подключения файла конфигурации для отслеживания изменений:

public static class LogFactory
{
    /// <summary>
    /// Create log whose name is the calling methods class name.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Configures the log repository if it hasn't been configured before.
    /// </para>
    /// <para>
    /// Creates a debug log message right after getting the logger, this follows
    /// the log4net recommendation to log first message as early as possible.
    /// </para>
    /// </remarks>
    /// <returns>Log ready for work.</returns>
    public static log4net.ILog Create()
    {
        var method = new StackTrace().GetFrame(1).GetMethod();
        var log = log4net.LogManager.GetLogger(method.DeclaringType);

        if (log4net.LogManager.GetRepository().Configured == false)
        {
            try
            {
                new FileIOPermission(FileIOPermissionAccess.Read,
                    AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)
                    .Demand();

                var configFile = new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
                log4net.Config.XmlConfigurator.ConfigureAndWatch(configFile);
                log.DebugFormat("Log4net configured and watching {0}", configFile.FullName);
            }
            catch (System.Security.SecurityException e)
            {
                log.DebugFormat("Unable to watch config file due to security permissions. {0}", e.ToString());
            }
        }

        log.DebugFormat("Logging {0}", log.Logger.Name);

        return log;
    }
}
1 голос
/ 14 декабря 2009

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

Debug - очень многословно, содержит много отладочной информации. Например, SQL-запросы.
Информация - полезная информация, которую полезно знать.
Предупреждение - ничего смертельного, но оператор должен знать о проблеме.
Ошибка - приложение теперь нестабильно, журнал содержит диагностическую информацию, такую ​​как сообщение об исключении и трассировка стека.

Используйте их в коде, например,

_log.Info("Updating object.");

написал бы сообщение уровня INFO любому заинтересованному слушателю.

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

<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
  </layout>
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
  <file value="c:\temp\servicelog.txt" />
  <appendToFile value="true" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline%exception" />
  </layout>
</appender>
<root>
  <level value="ERROR" />
  <appender-ref ref="ConsoleAppender" />
</root>
<logger name="Warehouse.Core">
  <level value="INFO" />
  <appender-ref ref="FileAppender" />
</logger>
</log4net>

Это говорит: все сообщения об ошибках на консоль, все сообщения INFO от регистратора Warehouse.Core к данному файлу.

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


Относительно затрат по сравнению с выгодами от ведения журнала, безусловно, есть грань между слишком большим количеством ведения журнала (огромными журналами, которые никто не будет использовать) и недостаточным (единственная строка, которая говорит "сбой").

Моя политика состоит в том, чтобы регистрировать в INFO то, что может дать сбой: внешние зависимости (запуск приложения, вызовы служб, соединения SQL), а в DEBUG - более сложные кусочки мясного кода (диагностические сообщения в бизнес-логике, отдельные вызовы SQL, некоторые методы). вызовы).

Необычные ситуации, когда (например) приняты значения по умолчанию, которые обычно не переходят в WARN, а исключения - в ERROR или FATAL.

Также: имейте в виду, что у WCF есть превосходная программа просмотра трассировки служб, которая позволяет вам "детализировать" отдельные пакеты и то, как они обрабатываются обоими концами стека. Это также доступно конфигурацией без изменений кода. Из-за этого я, как правило, просто делаю очень сокращенное ведение журнала вызовов и ответов службы WCF.

0 голосов
/ 14 декабря 2009

Вероятно, есть лучший способ сделать это для WCF; для WinForms вы можете посмотреть PostSharp . Это позволит вам регистрировать вызовы методов, не загромождая ваш код. За кулисами вы все равно будете использовать отличный log4net.

Предостережение: я сам этим не пользовался; Я видел очень впечатляющую презентацию в лагере кодов.

0 голосов
/ 14 декабря 2009

Журнал событий для просмотра событий.

Используйте с умом INFO ПРЕДУПРЕЖДЕНИЕ ОТЛАДКИ и ОШИБКИ.

при разработке покажите все (используйте консоль на стороне сервера - см. Ниже) на производстве, регистрируйте только ошибки (настраивается)

Я создаю регистратор в начале каждого класса, давая ему typeof (myClass), но это необязательно ...

Я размещаю WCF в DEV как консольное приложение, поэтому просматривать журнал сервера легко и в консоли, но как только он становится сервисом, вам нужно использовать средство просмотра событий ....

ах - и это очень быстро, если вы сравните его с "временем вызовов" WCF (звонками от клиента к серверу), так что это не будет реально влиять на ваше время, если у вас нет чего-то вроде журналов как сумасшедших (например, nHibernate) )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...