我正在尝试使用Windsor Logging Facility作为NLog的包装器。除了callsite
信息发出包装类和方法名称而不是实际的调用者信息之外,所有内容似乎都正常工作。从一个基本的搜索,这听起来像一个显而易见的事情,但我找不到解决方案。有什么想法吗?
我将设施添加到容器中:
container.AddFacility<LoggingFacility>(f => f.UseNLog());
在我的课程中,我有公共属性,我正在使用容器实例化该类。
private ILogger logger = NullLogger.Instance;
public ILogger Logger
{
get
{
return logger;
}
set
{
logger = value;
}
}
我的NLog.config配置为发出调用点信息:
${callsite: className=true: fileName=true: includeSourcePath=true: methodName=true}
答案 0 :(得分:1)
在我看来,没有实现包裹NLog Logger对象的Castle NLogLogger包装器,因此保留了调用站点信息。有关包装器的实现,请参阅this link into the Castle repository。
为了完整性,这里是Castle实现的缩写示例:
public class NLogLogger : ILogger
{
public NLogLogger(Logger logger, NLogFactory factory)
{
Logger = logger;
Factory = factory;
}
internal NLogLogger() {}
public bool IsDebugEnabled
{
get { return Logger.IsDebugEnabled; }
}
public void Debug(string message)
{
Logger.Debug(message);
}
}
关键问题是“Debug”方法(所有其他日志记录方法)使用NLog Logger对象上的相应方法。 NLog Logger上的日志记录方法使用调用函数/方法作为调用站点(这不是100%正确,但实际上在这种情况下会发生这种情况)。因此,在这个包装器的情况下,调用站点将是Castle NLog包装器实现。编写包装器以保留调用站点的一种正确方法是使用NLog Logger上的Log方法,将包装器的Type作为第一个参数传递。 NLog将上升到堆栈,直到MethodInfo的Type与传递给Log方法的Type相同。堆栈的下一个方法是调用站点。
为了正确保留调用站点信息,Debug方法应如下所示:
public void Debug(string message)
{
LogEventInfo logEvent = new LogEventInfo(LogLevel.Debug, Logger.Name, message);
Logger.Log(typeof(NLogLogger), logEvent);
}
请参阅我过去发布的有关正确包装NLog记录器的答案的链接,以便保留呼叫站点信息:
How to retain callsite information when wrapping NLog
Nlog Callsite is wrong when wrapper is used
有关如何扩展NLog记录器的一些示例,另请参阅this link到NLog的源存储库。