Как использовать log4net с внедрением зависимостей - PullRequest
76 голосов
/ 02 июня 2009

Я пытаюсь выяснить, каков правильный подход и использование log4net со структурой внедрения зависимостей.

Log4Net использует интерфейс ILog, но требует, чтобы я позвонил

LogManager.GetLogger(Reflection.MethodBase.GetCurrentMethod().DeclaringType)

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

Должен ли я как-то добавить еще один слой абстракции?

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

log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;

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

public static class Logger
{
    public static void LogException(Type declaringType, string message, Exception ex)
    {
        log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;
        ILog log = LogManager.GetLogger(declaringType);
        log.Error(message, ex);
    }
}

Ответы [ 4 ]

62 голосов
/ 02 июня 2009

Я думаю, вы не видите здесь лес за деревьями. ILog и LogManager являются легким фасадом, почти 1: 1, эквивалентным протоколированию общего доступа Apache, и фактически не связывают ваш код с остальной частью log4net.

<rant>
Я также обнаружил, что почти всегда , когда кто-то создает оболочку MyCompanyLogger вокруг log4net, он сильно упускает суть и либо теряет важные и полезные возможности платформы, выбрасывает полезную информацию, теряет возможный прирост производительности при использовании даже упрощенный интерфейс ILog, или все вышеперечисленное. Другими словами, упаковка log4net во избежание связи с ним является анти-паттерном .
</rant>

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

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

public class TotalMemoryProperty
{
    public override string ToString()
    {
        return GC.GetTotalMemory(false).ToString();
    }
}

Затем подключить его во время запуска:

GlobalContext.Properties["TotalMemory"] = new TotalMemoryProperty();
2 голосов
/ 12 марта 2014

Другой способ сделать это - подключить последовательность регистрации контейнера интерфейса ILog log4net следующим образом: (используя в качестве примера Castle в контексте ASP.NET ниже)

container.Register(Component.For<ILog>().LifeStyle
    .PerWebRequest.UsingFactoryMethod(() => LogManager.GetLogger(
    MethodBase.GetCurrentMethod().DeclaringType)));

и просто добавляйте конструктор ILog всякий раз, когда вам это нужно.

2 голосов
/ 02 июня 2009

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

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

2 голосов
/ 02 июня 2009

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

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