我有一个包装NLog的类(称为NLogger).我的日志保存到我的数据库中.我遇到问题的是如何显示日志记录发生的位置.我有这个
<parameter name="@Logger" layout="${callsite}"/>
Run Code Online (Sandbox Code Playgroud)
但这只是显示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);
}
Run Code Online (Sandbox Code Playgroud)
wag*_*ghe 41
问题是你的包装器没有正确包装.下面是一个如何正确包装NLog的示例,直接从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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
关键是将记录器包装器的类型传递给对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);
}
Run Code Online (Sandbox Code Playgroud)
要跳过几帧并深入了解包装调用者上下文,请在App.config中设置,或者在程序中设置着名的修饰符:
skipFrames = 1
例如:请参见本页面为${callsite:skipFrames=Integer}
与此页面为${callsite-linenumber:skipFrames=Integer}
我建议你在包装器中使用这种格式:
${callsite:fileName=true:includeSourcePath=false:skipFrames=1}
Run Code Online (Sandbox Code Playgroud)
此设置的输出如下:
... {LicenseServer.LSCore.MainThreadFunction(LSCore.cs:220)} ...
| 归档时间: |
|
| 查看次数: |
15006 次 |
| 最近记录: |