c# - 包装 NLog 时如何保留调用点信息

标签 c# logging nlog

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

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

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

这是我的包装方法

        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 的示例,直接取自 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 调用的类型。这将是实际调用包装器的代码。

在你的例子中,你的记录器看起来像这样:

    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);
    }

关于c# - 包装 NLog 时如何保留调用点信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7412156/

相关文章:

c# - Task.Factory.StartNew 不会等待任务完成?

c# - 使用linq查找不相交的数据集

java - logback:[encoder] 没有适用的操作,当前 ElementPath 是 [[configuration][appender][encoder]]

php - 变更日志文件 : YAML vs JSON vs CSV

c# - NLog 给出异常可能的解释是缺少零参数和单个参数 Common.Logging.Configuration.NameValueCollection 构造函数

.net - 无法加载 Exchange powershell 管理单元 : The type initializer for 'Microsoft.Exchange.Data.Directory.Globals' threw an exception

c# - 如何在从整数数组创建的列表中使用 ANY?

http - 如何读取服务器日志文件?

c# - NLog - 文件目标文件名的参数

c# - 如何使用 NEST QueryString 并转义特殊字符?