0

我试图让 Common.Logging 调用我的自定义记录器,但从未调用 WriteInternal。我错过了某个地方的配置吗?在我的 ASP.NET Owin 项目中,Startup.cs 有

        LogManager.Adapter = new HubLoggerAdapter(resolver.Kernel.Get<ILogger>());

其中 ILogger 是我的自定义记录器。HubLoggerAdapter 看起来像

public class HubLoggerAdapter : ILoggerFactoryAdapter
{
    private ILogger _logger;

    public HubLoggerAdapter(ILogger logger)
    {
        _logger = logger;
    }

    public ILog GetLogger(Type type)
    {
        if (type == null)
        {
            throw new ArgumentNullException("type");
        }

        try
        {
            return new HubLogger(_logger);
        }
        catch (Exception ex)
        {
            var x = ex.Message;
        }
        return null;
    }

    public ILog GetLogger(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException();
        }

        try
        {
            return new HubLogger(_logger);
        }
        catch (Exception ex)
        {
            var x = ex.Message;
        }
        return null;
    }
}

记录器看起来像

public class HubLogger : AbstractLogger
{
    public override bool IsTraceEnabled { get { return _logLevel.HasFlag(LogLevel.Trace); } }
    public override bool IsDebugEnabled { get { return _logLevel.HasFlag(LogLevel.Debug); } }
    public override bool IsErrorEnabled { get { return _logLevel.HasFlag(LogLevel.Error); } }
    public override bool IsFatalEnabled { get { return _logLevel.HasFlag(LogLevel.Fatal); } }
    public override bool IsInfoEnabled { get { return _logLevel.HasFlag(LogLevel.Info); } }
    public override bool IsWarnEnabled { get { return _logLevel.HasFlag(LogLevel.Warn); } }

    private LogLevel _logLevel;
    private ILogger _logger;

    public HubLogger(ILogger logger)
        : this(logger, LogLevel.All)
    {

    }

    public HubLogger(ILogger logger, LogLevel level)
        : base()
    {            
        _logLevel = level;
        _logger = logger;

        _logger.Log("initiating HubLogger");
    }

    protected override void WriteInternal(LogLevel level, object message, Exception exception)
    {
        switch (level)
        {
            case LogLevel.All:
            case LogLevel.Trace:
            case LogLevel.Debug:
            case LogLevel.Info:
            case LogLevel.Warn:
            case LogLevel.Error:
                _logger.Log(message.ToString());
                if (exception != null)
                {
                    _logger.Log(exception);
                }
                break;
            case LogLevel.Off:
                break;

            default:
                throw new ArgumentOutOfRangeException("level", level, "invalid logging level");
        }
    }
}

如果我调用 var logger = LogManager.GetLogger(); logger.Warn("我还活着。");

我看到“启动 HubLogger”,但我的消息永远不会调用 WriteInternal。这真的很奇怪。任何见解都非常感谢。

编辑 1.尝试根据建议添加带有 NameValueCollection 的构造函数,但它不起作用。特别添加

    private ILogger _logger;
    public IKernel Kernel { get; set; }

    public HubLoggerAdapter(NameValueCollection props)
    {

// _logger = props["logger"]; }

    public HubLoggerAdapter(ILogger logger)
    {
        _logger = logger;
    }

并使用

        var props = new NameValueCollection();
        var adapter = new HubLoggerAdapter(props);
        adapter.Kernel = resolver.Kernel;
        LogManager.Adapter = adapter;

不知道为什么构造函数会有所作为。

4

1 回答 1

0

通过从 AbstractSimpleLogger 和 AbstractSimpleLoggerFactoryAdapter 派生,我终于得到了这个工作。

public class HubLogger : AbstractSimpleLogger
{
    private ILogger _logger;

    public HubLogger(ILogger logger, string logName, LogLevel logLevel, bool showLevel, bool showDateTime, bool showLogName, string dateTimeFormat)
        : base(logName, logLevel, showLevel, showDateTime, showLogName, dateTimeFormat)
    {
        _logger = logger;
    }

    protected override void WriteInternal(LogLevel level, object message, Exception e)
    {
        switch (level)
        {
            case LogLevel.All:
            case LogLevel.Trace:
            case LogLevel.Debug:
            case LogLevel.Info:
            case LogLevel.Warn:
            case LogLevel.Error:
                // Use a StringBuilder for better performance
                StringBuilder sb = new StringBuilder();
                FormatOutput(sb, level, message, e);

                if (e != null)
                {
                    _logger.Log(e);
                }
                _logger.Log(sb.ToString());
                break;
            case LogLevel.Off:
                break;

            default:
                throw new ArgumentOutOfRangeException("level", level, "invalid logging level");
        }
    }

    private ILogger _logger;

    public HubLoggerAdapter(ILogger logger)
        : base(null)
    {
        _logger = logger;
    }

    protected override ILog CreateLogger(string name, LogLevel level, bool showLevel, bool showDateTime, bool showLogName, string dateTimeFormat)
    {
        ILog log = new HubLogger(_logger, name, level, showLevel, showDateTime, showLogName, dateTimeFormat);
        return log;
    }
}
于 2016-10-27T22:42:02.430 回答