Nlog Callsite неправильно при использовании оболочки - PullRequest
14 голосов
/ 27 февраля 2011

Я использую NLog для регистрации, я использую оболочку для вызова методов журнала, моя проблема: если я пытаюсь напечатать информацию о сайте вызова (${callsite}), он печатает метод оболочки, а не оригинальный метод что заставило регистратор войти.

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

Ответы [ 3 ]

20 голосов
/ 28 февраля 2011

Смотрите мой ответ на этот вопрос:

Проблема с определенным именем регистратора NLog

Я скопировал пример кода (для сокращенной оболочки NLog) из этого ответа, чтобы избежать некоторых проблем:

  class NLogLogger : ILogger
  {
    private NLog.Logger logger;

    //The Type that is passed in is ultimately the type of the current object that
    //Ninject is creating.  In the case of my example, it is Class1 and Class1 is
    //dependent on ILogger.
    public NLogLogger(Type t)
    {
      logger = NLog.LogManager.GetLogger(t.FullName);
    }

    //Trace, Warn, Error, Fatal eliminated for brevity

    public bool IsInfoEnabled
    {
      get { return logger.IsInfoEnabled; }
    }

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

    public void Info(string format, params object [] args)
    {
      if (logger.IsInfoEnabled)
      {
        Write(LogLevel.Info, format, args);
      }
    }

    public void Debug(string format, params object [] args)
    {
      if (logger.IsDebugEnabled)
      {
        Write(LogLevel.Debug, format, args);
      }
    }

    private void Write(LogLevel level, string format, params object [] args)
    {
      LogEventInfo le = new LogEventInfo(level, logger.Name, null, format, args);
      logger.Log(typeof(NLogLogger), le);
    }
  }

Обратите внимание, что этот ответ был дан в контексте NInject. Тот же принцип применяется к переносу NLog, даже если вы не используете NInject. Ключ сообщает NLog тип вашей оболочки.

Это пример того, как правильно написать оболочку NLog (т. Е. Для поддержки информации сайта вызова). Ключ находится в методе записи. Обратите внимание, как он использует метод журнала NLog. Также обратите внимание, что в качестве первого параметра передается тип класса-оболочки. NLog использует информацию о типе для навигации по стеку вызовов. Как только он видит метод, для которого DeclaringType является передаваемым типом (то есть типом оболочки), он знает, что следующий кадр в стеке является вызывающим методом.

Также см. Эту ссылку (на исходный репозиторий NLog), где приведены еще два примера "расширения" Logger. Один за перенос, другой за наследование:

https://github.com/jkowalski/NLog/tree/master/examples/ExtendingLoggers

Я не уверен на 100%, но я думаю, что вы не можете просто обернуть NLog и делегировать метод Info, Debug, Warn и т. Д. NLog следующим образом:

class MyNLogWrapper
{
  private readonly Logger logger = LogManager.GetCurrentClassLogger();

  public void Info(string msg)
  {
    logger.Info(msg);
  }
}

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

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

0 голосов
/ 21 сентября 2016

Ребята После нескольких дней напряженной работы и поиска. Наконец, я просто использую один простой класс, построенный Nlog Wrapper, который может сохранить $ {CallSite} и получить правильное имя регистратора при создании экземпляра Nlog Wrapper.Я поставлю код, как следует с простым комментарием.Как видите, я использую Stacktrace, чтобы получить правильное имя логгера.Используйте write и writewithex, чтобы зарегистрировать logevnet, чтобы он мог сохранить сайт вызовов.Если у вас есть какие-либо вопросы, пожалуйста, дайте мне знать.

 public  class NlogWrapper 
    {  
        private  readonly NLog.Logger _logger; //NLog logger

    /// <summary>
    /// This is the construtor, which get the correct logger name when instance created  
    /// </summary>

    public NlogWrapper()
        {
        StackTrace trace = new StackTrace();

        if (trace.FrameCount > 1)
        {
            _logger = LogManager.GetLogger(trace.GetFrame(1).GetMethod().ReflectedType.FullName);
        }
        else //This would go back to the stated problem
        {
            _logger = LogManager.GetCurrentClassLogger();
        }
    }
    /// <summary>
    /// These two method are used to retain the ${callsite} for all the Nlog method  
    /// </summary>
    /// <param name="level">LogLevel.</param>
    ///  <param name="format">Passed message.</param>
    ///  <param name="ex">Exception.</param>
    private void Write(LogLevel level, string format, params object[] args)
    {
        LogEventInfo le = new LogEventInfo(level, _logger.Name, null, format, args);
        _logger.Log(typeof(NlogWrapper), le);
    }
    private void WriteWithEx(LogLevel level, string format,Exception ex, params object[] args)
    {
        LogEventInfo le = new LogEventInfo(level, _logger.Name, null, format, args);
        le.Exception = ex;
        _logger.Log(typeof(NlogWrapper), le);
    }


    #region  Methods
    /// <summary>
    /// This method writes the Debug information to trace file
    /// </summary>
    /// <param name="message">The message.</param>
    public  void Debug(String message)
        {
            if (!_logger.IsDebugEnabled) return;

        Write(LogLevel.Debug, message);
    }  

    public  void Debug(string message, Exception exception, params object[] args)
    {
        if (!_logger.IsFatalEnabled) return;
        WriteWithEx(LogLevel.Debug, message, exception);
    }

    /// <summary>
    /// This method writes the Information to trace file
    /// </summary>
    /// <param name="message">The message.</param>
    public  void Info(String message)
        {
            if (!_logger.IsInfoEnabled) return;
        Write(LogLevel.Info, message);
    }

    public  void Info(string message, Exception exception, params object[] args) 
    {
        if (!_logger.IsFatalEnabled) return;
        WriteWithEx(LogLevel.Info, message, exception);
    }
    /// <summary>
    /// This method writes the Warning information to trace file
    /// </summary>
    /// <param name="message">The message.</param>
    public  void Warn(String message)
        {
            if (!_logger.IsWarnEnabled) return;
          Write(LogLevel.Warn, message); 
        }

    public  void Warn(string message, Exception exception, params object[] args)
    {
        if (!_logger.IsFatalEnabled) return;
        WriteWithEx(LogLevel.Warn, message, exception);
    }

    /// <summary>
    /// This method writes the Error Information to trace file
    /// </summary>
    /// <param name="error">The error.</param>
    /// <param name="exception">The exception.</param>
    //   public static void Error( string message)
    //  {
    //    if (!_logger.IsErrorEnabled) return;
    //  _logger.Error(message);
    //}

    public  void Error(String message) 
    {
        if (!_logger.IsWarnEnabled) return;
        //_logger.Warn(message);
        Write(LogLevel.Error, message);
    }
    public void Error(string message, Exception exception, params object[] args)
    {
        if (!_logger.IsFatalEnabled) return;
        WriteWithEx(LogLevel.Error, message, exception);
    }  


    /// <summary>
    /// This method writes the Fatal exception information to trace target
    /// </summary>
    /// <param name="message">The message.</param>
    public void Fatal(String message)
        {
            if (!_logger.IsFatalEnabled) return;
         Write(LogLevel.Fatal, message);
    }

    public void Fatal(string message, Exception exception, params object[] args)
    {
        if (!_logger.IsFatalEnabled) return;
        WriteWithEx(LogLevel.Fatal, message, exception);
    }

    /// <summary>
    /// This method writes the trace information to trace target
    /// </summary>
    /// <param name="message">The message.</param>
    /// 
    public  void Trace(string message, Exception exception, params object[] args)  
    {
        if (!_logger.IsFatalEnabled) return;
        WriteWithEx(LogLevel.Trace, message, exception);
    }
    public  void Trace(String message)
        {
            if (!_logger.IsTraceEnabled) return;
            Write(LogLevel.Trace, message);
    }

        #endregion

    }
0 голосов
/ 11 декабря 2014

Вы также можете добавить это в свой класс NLogLogger и вызвать его в первой строке метода Write.

    protected void GetCurrentClassLogger()
    {
        //This should take you back to the previous frame and context of the Log call
        StackTrace trace = new StackTrace();

        if (trace.FrameCount > 1)
        {
            logger = LogManager.GetLogger(trace.GetFrame(1).GetMethod().ReflectedType.FullName);
        }
        else //This would go back to the stated problem
        {
            logger = LogManager.GetCurrentClassLogger();
        }
    }


    private void Write(LogLevel level, string format, params object[] args)
    {
        //added code
        GetCurrentClassLogger();

        LogEventInfo le = new LogEventInfo(level, logger.Name, null, format, args);
        logger.Log(typeof(NLogLogger), le);
    }
...