包装NLog时如何保留callsite信息 [英] How to retain callsite information when wrapping NLog

查看:28
本文介绍了包装NLog时如何保留callsite信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包装 NLog 的类(称为 NLogger).我的日志保存到我的数据库中.我遇到的问题是如何显示日志记录发生的位置.我有这个

I have a class that wraps NLog (called NLogger). My logs are saved to my database. The thing I'm having a problem with is how do I show where the logging occured. I have this

<parameter name="@Logger" layout="${callsite}"/>  

但这只是显示 Core.Logging.Loggers.NLogLogger.Log 这是我的 NlogWrapper 而不是调用我的包装器的类.

but this just shows Core.Logging.Loggers.NLogLogger.Log which is my NlogWrapper not the class which calls my wrapper.

这是我的包装方法

        public void Log(LogType messageType, Type context, string message, Exception exception)
        {
            NLog.Logger logger = NLog.LogManager.GetLogger(context.Name);
            LogLevel logLevel = LogLevel.Info; // Default level to info

            switch (messageType)
            {
                case LogType.Debug:
                    logLevel = LogLevel.Debug;
                    break;
                case LogType.Info:
                    logLevel = LogLevel.Info;
                    break;
                case LogType.Warning:
                    logLevel = LogLevel.Warn;
                    break;
                case LogType.Error:
                    logLevel = LogLevel.Error;
                    break;
                case LogType.Fatal:
                    logLevel = LogLevel.Fatal;
                    break;
                default:
                    throw new ArgumentException("Log message type is not supported");                    
            }

            logger.Log(logLevel, message, exception);
        }

推荐答案

问题是您的包装器没有正确包装.这是一个如何正确包装 NLog 的示例,直接取自 NLog 的源树:

The problem is that your wrapper is not wrapping correctly. Here is an example of how to wrap NLog correctly, taken directly from the source tree of NLog:

using System;
using System.Text;
using NLog;

namespace LoggerWrapper
{    
  /// <summary>    
  /// Provides methods to write messages with event IDs - useful for the Event Log target.    
  /// Wraps a Logger instance.    
  /// </summary>    
  class MyLogger    
  {        
    private Logger _logger;        

    public MyLogger(string name)        
    {            
      _logger = LogManager.GetLogger(name);        
    }        

    public void WriteMessage(string eventID, string message)           
    {            
      ///            
      /// create log event from the passed message            
      ///             
      LogEventInfo logEvent = new LogEventInfo(LogLevel.Info, _logger.Name, message);


      //
      // set event-specific context parameter            
      // this context parameter can be retrieved using ${event-context:EventID}            
      //            
      logEvent.Context["EventID"] = eventID;            
      //             
      // Call the Log() method. It is important to pass typeof(MyLogger) as the            
      // first parameter. If you don't, ${callsite} and other callstack-related             
      // layout renderers will not work properly.            
      //            
      _logger.Log(typeof(MyLogger), logEvent);        
    }    
  }
}

关键是将记录器包装器的类型传递给对 Log 的调用.当 NLog 尝试查找调用站点时,它会向上移动堆栈,直到第一个调用方法的声明类型不是传递给 Log 调用的类型.这将是实际调用您的包装器的代码.

The key is passing the type of your logger wrapper to the call to Log. When NLog tries to find the callsite, it goes up the stack until the first calling method whose declaring type is NOT the type passed to the Log call. This will be the code that is actually calling your wrapper.

在您的情况下,您的记录器将如下所示:

In your case, your logger would look something like this:

    public void Log(LogType messageType, Type context, string message, Exception exception)
    {
        NLog.Logger logger = NLog.LogManager.GetLogger(context.Name);
        LogLevel logLevel = LogLevel.Info; // Default level to info

        switch (messageType)
        {
            case LogType.Debug:
                logLevel = LogLevel.Debug;
                break;
            case LogType.Info:
                logLevel = LogLevel.Info;
                break;
            case LogType.Warning:
                logLevel = LogLevel.Warn;
                break;
            case LogType.Error:
                logLevel = LogLevel.Error;
                break;
            case LogType.Fatal:
                logLevel = LogLevel.Fatal;
                break;
            default:
                throw new ArgumentException("Log message type is not supported");                    
        }

        //
        // Build LogEvent here...
        //
        LogEventInfo logEvent = new LogEventInfo(logLevel, context.Name, message);
        logEvent.Exception = exception;

        //
        // Pass the type of your wrapper class here...
        //
        logger.Log(typeof(YourWrapperClass), logEvent);
    }

这篇关于包装NLog时如何保留callsite信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆