WriteInternal не вызывается в Common.Logging, производном от AbstractLogger

Я пытаюсь заставить 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;

не уверен, почему конструктор будет иметь какое-либо значение.


person tofutim    schedule 27.10.2016    source источник
comment
netcommon.sourceforge.net/docs/1.2.0/reference/ html/: 1.5.1: Важно: любая реализация должна предоставлять общедоступный конструктор, принимающий параметр NameValueCollection.   -  person Caramiriel    schedule 27.10.2016
comment
Интересно, как я могу передать туда свой объект тогда.   -  person tofutim    schedule 28.10.2016
comment
и это тоже очень странно, разве мы не создаем это сами? Я попробовал ваше предложение, но это не помогло   -  person tofutim    schedule 28.10.2016


Ответы (1)


Наконец-то я заставил это работать, наследуя от 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;
    }
}
person tofutim    schedule 27.10.2016