Подтвердить что ты не робот

Каковы наилучшие методы включения ведения журнала с помощью log4net?

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

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

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

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

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

-

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

// 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

Ответ 3

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

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

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

Ответ 4

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

  • Функция Enter/Exit
  • Основные логические шаги внутри функции
  • Подробное ведение журнала для всех промежуточных вычислений

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

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

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

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

Ответ 5

Одна из замечательных особенностей log4net заключается в том, что вы можете записывать события в разные категории. По умолчанию используются Debug, Info, Warning и Error. Мне это нравится

Отладка - очень многословная, содержит много отладочной информации. Например, 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>

Это говорит: все сообщения ERROR на консоль, все сообщения INFO из регистратора Warehouse.Core в данный файл.

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


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

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

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

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

Ответ 6

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

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

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

Сосредоточьтесь на деталях DEBUG в тех областях, где вы либо знаете, либо подозреваете, что у вас будут проблемы (просто спросите 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;
    }
}

Ответ 7

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

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

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

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

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

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

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

Ответ 8

Зарегистрировать события для просмотра событий.

Используйте разумно INFO DEBUG WARNING и ERROR.

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

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

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

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

Ответ 9

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

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