Log4Net Wrapper类会是什么样子?[英] What would a Log4Net Wrapper class look like?

本文是小编为大家收集整理的关于Log4Net Wrapper类会是什么样子?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我一直在寻找.NET(C#)的记录框架,并决定在stackoverflow上阅读一些问题/答案线程后,决定让Log.net a Go a Go.我看到人们一遍又一遍地提到他们在log4net上使用包装班,我想知道这会是什么样.

我将代码分为不同的项目(数据访问/业务/WebService/..). Log4net包装器类别如何?包装班是否需要包含在所有项目中?我应该一起构建它吗?

包装纸应该是单身班吗?

推荐答案

本质上,您创建一个接口,然后创建该接口的具体实现,该接口直接包装Log4net的类和方法.可以通过创建更多具体类来包装其他日志记录系统,从而包含这些系统的其他类和方法.最后,使用工厂根据配置设置或代码更改行创建包装器实例. (注意:您可以使用倒置控制 a href =" http://structuremap.sourceforge.net/default.htm" rel =" noreferrer"> structuremap .)

public interface ILogger
{
    void Debug(object message);
    bool IsDebugEnabled { get; }

    // continue for all methods like Error, Fatal ...
}

public class Log4NetWrapper : ILogger
{
    private readonly log4net.ILog _logger;

    public Log4NetWrapper(Type type)
    {
        _logger = log4net.LogManager.GetLogger(type);
    }

    public void Debug(object message)
    {
        _logger.Debug(message);
    }

    public bool IsDebugEnabled
    {
        get { return _logger.IsDebugEnabled; }
    }

    // complete ILogger interface implementation
}

public static class LogManager
{
    public static ILogger GetLogger(Type type)
    {
        // if configuration file says log4net...
        return new Log4NetWrapper(type);
        // if it says Joe's Logger...
        // return new JoesLoggerWrapper(type);
    }
}

以及在您的类中使用此代码的一个示例(称为静态可读字段):

private static readonly ILogger _logger =
    LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

您可以使用以下方式获得相同的性能友好效果:

private static readonly ILogger _logger = 
    LogManager.GetLogger(typeof(YourTypeName));

前一个示例被认为更可维护.

您不想创建一个单身人士来处理所有日志记录,因为log4net log是调用类型的日志.每种类型都使用自己的记录器,而不仅仅是在日志文件中看到所有消息的单一类型.

由于您的实施应相当可重复使用(您组织中的其他项目),因此您可以将其自身组成,或者理想地将其包含在您自己的个人/组织的框架/公用事业集团中.请勿在每个业务/数据/UI组件中分别重新列入类,这是不可维护的.

其他推荐答案

假设您要去上面的CFeduke答案,您也可以在LogManager上添加一个过载:

public static ILogger GetLogger()
{
    var stack = new StackTrace();
    var frame = stack.GetFrame(1);
    return new Log4NetWrapper(frame.GetMethod().DeclaringType);
}

那样在代码中您可以使用:

private static readonly ILogger _logger = LogManager.GetLogger();

而不是其中任何一个:

private static readonly ILogger _logger =
    LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILogger _logger = 
    LogManager.GetLogger(typeof(YourTypeName));

有效地等效于第一个替代方案(即使用MethodBase.GetCurrentMethod().DeclaringType>),只有一点简单.

其他推荐答案

您打算从编写Log4net的包装器中有什么好处.我建议您在周围写包装纸之前先了解Log4net课程. CFEDUKE在他的回答中对如何编写上述包装器是正确的,但是除非您需要在他的示例中添加实际功能,否则包装器只会成功地减慢日志记录过程,并为将来的维护者增添复杂性.当.NET中可用的重构工具使此类更改超级简单时,这尤其如此.

本文地址:https://www.itbaoku.cn/post/627576.html

问题描述

I have been looking for a logging framework for .net (c#) and decided to give log4net a go after reading up on a few question/answer threads here on stackoverflow. I see people mentioning over and over that they use a wrapper class for log4net and I am wonder what that would look like.

I have my code split up into different projects (data access/business/webservice/..). How would a log4net wrapper class look like? Would the wrapper class need to be included in all of the projects? Should I build it as a separate project all together?

Should the wrapper be a singleton class?

推荐答案

Essentially you create an interface and then a concrete implementation of that interface that wraps the classes and methods of Log4net directly. Additional logging systems can be wrapped by creating more concrete classes which wrap other classes and methods of those systems. Finally use a factory to create instances of your wrappers based on a configuration setting or line of code change. (Note: you can get more flexible - and complex - using an Inversion of Control container such as StructureMap.)

public interface ILogger
{
    void Debug(object message);
    bool IsDebugEnabled { get; }

    // continue for all methods like Error, Fatal ...
}

public class Log4NetWrapper : ILogger
{
    private readonly log4net.ILog _logger;

    public Log4NetWrapper(Type type)
    {
        _logger = log4net.LogManager.GetLogger(type);
    }

    public void Debug(object message)
    {
        _logger.Debug(message);
    }

    public bool IsDebugEnabled
    {
        get { return _logger.IsDebugEnabled; }
    }

    // complete ILogger interface implementation
}

public static class LogManager
{
    public static ILogger GetLogger(Type type)
    {
        // if configuration file says log4net...
        return new Log4NetWrapper(type);
        // if it says Joe's Logger...
        // return new JoesLoggerWrapper(type);
    }
}

And an example of using this code in your classes (declared as a static readonly field):

private static readonly ILogger _logger =
    LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

You can get the same slightly more performance friendly effect using:

private static readonly ILogger _logger = 
    LogManager.GetLogger(typeof(YourTypeName));

The former example is considered more maintainable.

You would not want to create a Singleton to handle all logging because Log4Net logs for the invoking type; its much cleaner and useful to have each type use its own logger rather than just seeing a single type in the log file reporting all messages.

Because your implementation should be fairly reusable (other projects in your organization) you could make it its own assembly or ideally include it with your own personal/organization's framework/utility assembly. Do not re-declare the classes separately in each of your business/data/UI assemblies, that's not maintainable.

其他推荐答案

Assuming you were going with something like cfeduke's answer above, you could also add an overload to your LogManager like this:

public static ILogger GetLogger()
{
    var stack = new StackTrace();
    var frame = stack.GetFrame(1);
    return new Log4NetWrapper(frame.GetMethod().DeclaringType);
}

That way in your code you can now just use:

private static readonly ILogger _logger = LogManager.GetLogger();

instead of either of these:

private static readonly ILogger _logger =
    LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILogger _logger = 
    LogManager.GetLogger(typeof(YourTypeName));

Which is effectively equivalent of the first alternative (i.e. the one that uses MethodBase.GetCurrentMethod().DeclaringType), only a little simpler.

其他推荐答案

What benefits are you planning on getting out of writing a wrapper for log4net. I'd recommend getting comfortable with the log4net classes first before writing a wrapper around them. cfeduke is right in his answer on how to write said wrapper, but unless you need to add actual functionality to his example a wrapper would only succeed in slowing the logging process down and adding complexity for future maintainers. This especially true when refactoring tools available in .Net make such changes super easy.