来自其他类的NLog namespace.name

时间:2013-05-06 11:00:44

标签: c# .net nlog

目前我有LogWrapper类,它初始化NLog并发送给它Info / Debug / Warning等。

所以其他类中的每个方法都从

开始
LogWrapper.Informational(string.Format(" {0} starts {1}", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name));

在LogWrapper中时:

private static readonly Logger s_log = LogManager.GetCurrentClassLogger();

public static void Informational(string fmt, Exception exception)
{
    s_log.Info("{0} {1}",fmt, exception.ToString());
}

问题是,由于调用类与访问日志包装器的日志不同,因此始终显示LogWrapper的namespace.methodname,因此会对MethodBase进行无用的调用。

有没有办法从实际访问NLog的不同类的类调用函数?

感谢

1 个答案:

答案 0 :(得分:3)

如果您主要对使用NLog包装器感兴趣但仍能够维护呼叫站点信息,请参阅我之前对此问题的回答:

Nlog Callsite is wrong when wrapper is used

简而言之,您可以使用NLog Log方法并传递包装器的类型。然后,如果您使用NLog callsite LayoutRenderer,NLog将能够找出呼叫站点信息,而无需您自己解决。

因此,您的LogWrapper可能有这样的方法:

public static void Informational(string fmt, Exception exception)
{
  LogEventInfo le = new LogEventInfo(LogLevel.Info, logger.Name, null, fmt, exception.ToString());
  logger.Log(typeof(LogWrapper), le);
}

关键是将包装器的类型(typeof(LogWrapper))作为第一个参数传递给Logger.Log。 NLog使用该值遍历调用堆栈,直到它将该类型视为当前MethodInfo的DeclaringType。 NLog将堆栈帧视为实际呼叫站点之前的最后一个堆栈帧,因此NLog在看到它后再上升一级。

你应该知道NLog也有一个Exception LayoutRenderer,所以你不必自己使用exception.ToString()。

虽然Daniel Hilgarth在他的评论中提到的问题有一些有趣的代码,但我认为你应该非常小心地添加一堆代码来确定NLog可以为你“免费”获取的信息。如果您只需要它用于记录目的,我建议让NLog为您解决。如果你需要其他目的,那么你可能别无选择,只能自己解决。

另外,我还建议不要使用这种风格进行日志记录调用:

LogWrapper.Informational(string.Format(" {0} starts {1}",   
    MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name));

如果您的LogWrapper.Informational方法委托给NLog的Logger.Info,那么在没有打开日志记录或者日志记录级别小于Info(例如Warn,Error,Fatal)的情况下,您正在做一些额外的工作。 。如果由于当前的日志记录级别设置,该语句实际上不会被记录,您仍在格式化字符串,并且您正在进行两次相对昂贵的调用以获取调用点信息。