当我在PatternLayout中使用%l或%L进行调试时,我得到扩展静态类的位置和该文件中的行号,而不是调用者的位置和行。任何标准记录方法都会产生正确的结果。有没有办法让扩展方法做到这一点?
我的部分Log4NetExtensions.cs
namespace Dashboard
{
public static partial class Util
{
public static void SqlError(this ILog log, SqlException sqle)
{
if (log.IsDebugEnabled)
{
string[] names = Enum.GetNames(typeof(Dashboard.Models.Response.DashError.StandardErrors));
int idx = Array.IndexOf(names, sqle.Message);
if (idx > 0)
{
log.Debug(sqle.Message);
}
else
{
log.Error(sqle);
}
}
else
{
log.Error(sqle);
}
}
}
}
编辑: 根据我的回答,我将log.Error()和log.Debug更改为此但它仍然打印Util而不是调用者:
log.Logger.Log(typeof(Util), Level.Error, sqle.Message, sqle);
答案 0 :(得分:1)
请参阅此处关于另一个问题的答案,了解如何在包装log4net时维护呼叫站点信息。
how to log method name when using wrapper class with Log4net
即使您正在编写扩展方法,您实际上也在包装log4net。该答案中描述的技术应该适用于扩展方法,也适用于包装器。您的解决方案应该是在您的包装器中使用Log方法而不是Info,Error等。作为Log方法的第一个参数,发送扩展方法静态类的类型。
您的扩展方法看起来像这样(未编译或测试):
namespace Dashboard
{
public static partial class Util
{
public static void SqlError(this ILog log, SqlException sqle)
{
if (log.IsDebugEnabled)
{
string[] names = Enum.GetNames(typeof(Dashboard.Models.Response.DashError.StandardErrors));
int idx = Array.IndexOf(names, sqle.Message);
if (idx > 0)
{
//Note that I am using the Logger member and then calling the Log method it.
log.Logger.Log(typeof(Util), LogLevel.Debug, sqle.Message, null);
}
else
{
//Not sure about this call because you want to log only the exception. Don't
//know if log4net will accept null as "message" parameter.
log.Logger.Log(typeof(Util), LogLevel.Error, null, sqle);
}
}
else
{
//Not sure about this call because you want to log only the exception. Don't
//know if log4net will accept null as "message" parameter.
log.Logger.Log(typeof(Util), LogLevel.Error, null, sqle);
}
}
}
}
如果它不能正常工作,我想你会明白这个想法。
更新
FWIW,我把这个小样本放在一起,然后使用扩展方法记录呼叫站点所需的方法(主要):
class Program
{
static void Main(string[] args)
{
var logger = LogManager.GetLogger("abc");
ILogger ilog = logger.Logger;
logger.Info("Hello");
logger.InfoExt("Hello2");
}
}
public static class Extensions
{
public static void InfoExt(this ILog logger, string message)
{
logger.Logger.Log(typeof(Extensions), Level.Info, message, null);
}
}