根据this log4net文章,您应检查是否在任何Log.Debug语句之前启用了调试以消除语句构造成本.是否有更好的替代方法,总是必须在任何日志语句之前检查是否(Log.IsDebugEnabled)?
Log4Net示例:
if (log.IsDebugEnabled)
{
log.Debug("This is entry number: " + i );
}
我不想支付语句构造的开销成本,但也不想在每个日志语句之前检查.
解决方法:
but also don’t want to check prior to every log statement
当你发现自己一遍又一遍地重复相同的代码时,听起来像是一个普通的抽象可能是有序的.在这种情况下,您可以为Log4Net创建自定义包装器.简单的事情:
public static class Logger
{
private static ILog _log;
static Logger()
{
log4net.Config.XmlConfigurator.Configure();
_log = log4net.LogManager.GetLogger("Log4Net");
}
public static void Debug(string message)
{
if (_log.IsDebugEnabled)
_log.Debug(message);
}
public static void Info(string message)
{
_log.Info(message);
}
public static void Warn(string message)
{
_log.Warn(message);
}
public static void Error(string message)
{
_log.Error(message);
}
public static void Error(string message, Exception ex)
{
_log.Error(message, ex);
}
public static void Fatal(string message)
{
_log.Fatal(message);
}
public static void Fatal(string message, Exception ex)
{
_log.Fatal(message, ex);
}
}
在这种情况下,我使记录器实例静态.我不是百分百肯定会一直按预期工作.通常我在依赖注入框架后面使用它,并将logger依赖项配置为单例,由框架处理.您可以使用实例方法将其设置为实例类,并将其放在静态工厂类之后.根据需要进行测试和调整.
这里有几个额外的好处:
>您在Log4Net中的依赖关系被隔离到一个类.因此,如果您想使用其他记录器,则只需更改一个类而不是整个项目中的所有内容.
>您可以轻松地在依赖注入器后面抽象它.
>您希望包含在所有日志记录语句中的任何其他常用功能都可以轻松地全局包含在此处.
我通常用于第三个好处的一个例子可能是这样的:
private static string GetLocation()
{
var frame = new StackTrace(1).GetFrame(1);
var method = frame.GetMethod();
return string.Format("{0}:{1}.{2}({3})", Environment.MachineName, method.ReflectedType.FullName, method.Name, frame.GetFileLineNumber().ToString());
}
这从运行时系统获得了更有意义的调试信息(尽管可能存在性能损失,对于大批量系统而言,值得测试).所以我的传递错误记录功能可能如下所示:
public void Error(string message, Exception ex)
{
_log.Error(string.Format("{0}:{1}", GetLocation(), message), ex);
}