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

У меня есть исполняемый файл, который в зависимости от предоставленного переключателя командной строки выглядит примерно так:

Program.cs —

namespace DiskSpaceReporting
{
    class Program
    {
        static void Main(string[] args)
        {
            if(args.Length == 1)
            {
                switch(args[0])
                {
                    case "-summarytotals":
                        SummaryDiskSpaceReporter.Run();
                        break;

                    case "-detailed":
                        DetailedDiskSpaceReporter.Run();
                        break;
                    //...other reporting types
                }



            }
        }
    }
}

SummaryDiskSpaceReporter.cs

namespace DiskSpaceReporting
{
    public class SummaryDiskSpaceReporter
    {
        private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static void Run()
        {
            log.Info(1234, "Starting");
            //...do work
            string message = Helpers.CreateMessage(messageID);
            //...do work
        }
    }
}

DetailedDiskSpaceReporter.cs

namespace DiskSpaceReporting
{
    public class DetailedDiskSpaceReporter
    {
        private static IEventIDLog log = EventIDLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static void Run()
        {
            log.Info(1234, "Starting");
            //...do work
            string message = Helpers.CreateMessage(messageID);
            //...do work
        }
    }
}

Helpers.cs

namespace DiskSpaceReporting
{
    public class Helpers
    {
        private static IEventIDLog log = ???            
        public static string CreateMessage(Guid messageID)
        {
            log.Info(9876, "Starting");
            //...do work
        }
    }
}

В моей конфигурации log4net у меня есть два отдельных регистратора, по одному для каждого из SummaryDiskSpaceReporter и DetailedDiskSpaceReporter, потому что их требования к журналированию различаются:

<root>
    <level value="ALL" />
    <appender-ref ref="ConsoleLogAppender" />
    <appender-ref ref="EventLogAppender" />
</root>

<logger name="DiskSpaceReporting.SummaryDiskSpaceReporter">
    <appender-ref ref="SummaryDiskSpaceReporterRollingFileAppender"/>
</logger>

<logger name="DiskSpaceReporting.DetailedDiskSpaceReporter">
    <appender-ref ref="DetailedDiskSpaceReporterRollingFileAppender"/>
</logger>

И SummaryDiskSpaceReporter, и DetailedDiskSpaceReporter вызывают вспомогательный метод в классе Helpers. Я хочу внести некоторые записи в методы вспомогательного класса.

Итак... вопрос в том, как заставить метод Helpers.CreateMessage() использовать тот же регистратор, что и его вызывающая сторона?

i.e.

SummaryDiskSpaceReporter.Run() -> использовать средство ведения журнала DiskSpaceReporting.SummaryDiskSpaceReporter DetailedDiskSpaceReporter.Run() -> использовать средство ведения журнала DiskSpaceReporting.DetailedDiskSpaceReporter.

Привет Кев


person Kev    schedule 23.10.2008    source источник


Ответы (1)


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

Вариант 1. Передать регистратор

Это не самый лучший вариант, но он должен работать нормально, если вы не возражаете против подключения своего помощника к регистратору. Просто разрешите вашему методу CreateMessage принимать IEventIDLog. Затем вы можете использовать это для входа в правильно переданный регистратор.

public static string CreateMessage(Guid messageID, IEventIDLog log)
{
    log.Info(9876, "Starting");
    //...do work
}

Не совсем блестит, но должно работать!

Вариант 2. Используйте стек вызовов

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

public static string CreateMessage(Guid messageID)
{
    StackFrame frame = new StackTrace().GetFrame(1);
    IEventIDLog log = EventIDLogManager.GetLogger(frame.GetMethod().DeclaringType);
    log.Info(9876, "Starting");
    //...do work
}

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

Вариант 3: использовать log4net

Это вариант, который мы хотим использовать, черт возьми, это то, что вопрос хочет получить в качестве ответа, но я еще не работал с ним пока нет. :) Просматривая log4net, мы находим классные вещи, такие как класс Hierarchy, который позволяет нам получить корневой регистратор.

Logger logger1 = ((log4net.Repository.Hierarchy.Hierarchy) log4net.LogManager.GetRepository()).Root;

Поэтому я уверен, что есть способ поднять регистратор на один уровень выше метода CreateMessage, теперь просто найти его. :)

person FryHard    schedule 23.10.2008
comment
Эй, спасибо за ответ .... Я думал о вариантах 1 и 2, но должен быть способ заставить log4net делать это бесплатно, так сказать. - person Kev; 23.10.2008