如何在实用程序类中获取辅助方法以在log4net中使用其调用者记录器?

时间:2008-10-23 04:48:10

标签: logging 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的类中调用辅助方法。我想在helper类方法中加入一些日志。

所以...问题是,如何让Helpers.CreateMessage()方法使用与其调用者相同的记录器?

即。

  

SummaryDiskSpaceReporter.Run() - &gt;使用   DiskSpaceReporting.SummaryDiskSpaceReporter   记录器DetailedDiskSpaceReporter.Run()    - &GT;使用DiskSpaceReporting.DetailedDiskSpaceReporter   记录器。

干杯 千电子伏

1 个答案:

答案 0 :(得分:2)

我一直在玩这个问题很长一段时间,不幸的是我不得不放弃一段时间并回归做“真正的”工作。我目前提出的内容如下:

选项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方法中提升一级,现在只是为了找到它。 :)