стратегия log4net на именованных регистраторах? - PullRequest
5 голосов
/ 13 января 2009

Я обычно объявляю следующее в каждом классе:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(
            System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

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

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

Но мне редко приходилось использовать этот «уровень» тонкой регистрации. Итак, я хотел бы увидеть, что другие используют. Используете ли вы вышеперечисленное, поскольку у меня есть ощущение, что многие используют именно это, или вы создаете именованные регистраторы, такие как «debug», «trace», «error», «moduleA» и т. Д., И делитесь регистратором среди различных типов , сборки?

Ответы [ 4 ]

11 голосов
/ 19 мая 2009

Я в основном использую

public class MyClass
{
    private static readonly ILog log = Log.Get<MyClass>();
}

где Log.Get - класс, который в основном делает это внутренне

return LogManager.GetLogger(typeof(T));

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

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

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

Поэтому я иду по пути внедрения экземпляра ILog, обычно с помощью инжектора конструктора, и передаю , как создать логгер в мою платформу DI на выбор

public class MyClass
{
    readonly ILog _log;

    public class MyClass(ILog log)
    {
        _log = log;
    }
}

Это позволяет для правильного разделения. Код больше не должен знать, как создаются логгеры. Большинство структур внедрения зависимостей имеют средства просмотра внедряемого типа и последующего использования этого для создания экземпляра журнала. Вот подход для log4net и Autofac .

2 голосов
/ 05 февраля 2009

Стоимость выполнения этого оригинального способа является экземпляром реализации ILog и времени, которое требуется для запуска "System.Reflection.MethodBase.GetCurrentMethod (). DeclaringType" при запуске.

Я помню, как изучал это несколько лет назад, и наша стоимость запуска составляла порядка 1 секунды на 10000 классов и менее мегабайта на 10 000 классов.

Учитывая такую ​​низкую стоимость, я никогда не оглядывался назад, учитывая гибкость, которую обеспечивает log4net.

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

method = new System.Diagnostics.StackTrace (). GetFrame (1) .GetMethod ();

стоит дорого , особенно если вызывается для каждого сообщения журнала.

0 голосов
/ 18 мая 2009

Инструментом, который вы можете использовать для ведения журнала, является PostSharp (http://www.postsharp.org/).). Существует платная и бесплатная (Express) версия. Я использовал ее только для регистрации границ метода, но я знаю, что вы также можете использовать ее для обработка ошибок. Между этими двумя задачами можно было бы позаботиться о большинстве ваших потребностей в журнале без написания кода в каждом классе.

0 голосов
/ 22 января 2009

В последнее время я создал что-то вроде этого:

public static class Logger
{
    private static bool isLoaded = false;       

    public static ILog Log
    {
        get
        {
            System.Reflection.MethodBase method;
            method = new System.Diagnostics.StackTrace().GetFrame(1).GetMethod();
            StringBuilder loggerName = new StringBuilder();
            loggerName.AppendFormat("{0}.{1}(", method.ReflectedType.FullName, method.Name);

            ParameterInfo[] parameters = method.GetParameters();
            string[] parametersStr = new string[parameters.Length];

            if (parameters.Length > 0)
            {
                for (int i = 0; i < parameters.Length; i++)
                {
                    parametersStr[i] = parameters[i].ToString();
                }
                loggerName.Append(String.Join(", ", parametersStr));
            }

            loggerName.Append(")");

            return GetLogger(loggerName.ToString());
        }
    }


    private static ILog GetLogger(string loggerName)
    {
        if (!isLoaded)
        {
            log4net.Config.XmlConfigurator.Configure();
        }
        return LogManager.GetLogger(loggerName);
    }
}

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

Пример использования:

Logger.Log.DebugFormat("Response [{0}]", xmlResponse);
...