我试图找出什么正确的模式和使用log4net是一个依赖注入框架。
Log4Net使用ILog接口,但要求我调用
LogManager.GetLogger(Reflection.MethodBase.GetCurrentMethod().DeclaringType)
在每个类或方法中我需要记录信息。这似乎违反了IoC原则,并使我使用Log4Net。
我应该以某种方式放在另一层抽象的地方吗?
log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;
我如何封装这个,所以我不必记得每次都做,仍然保持当前的方法是日志。我应该做这样的事情还是我完全错过了标记?
public static class Logger { public static void LogException(Type declaringType,string message,Exception ex) { log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName; ILog log = LogManager.GetLogger(declaringType); log.Error(message,ex); } }
我想你没有在这里看到树的森林。 ILog和LogManager是一个轻量级的外观,几乎1:1等同于Apache commons-logging,并且实际上并不将您的代码与log4net的其余部分耦合。
< rant>
我也发现,当有人在log4net周围创建一个MyCompanyLogger包装器时,他们错过了这一点,并且会丢失重要的和有用的框架功能,丢弃有用的信息,甚至使用简化的ILog接口,或所有上述。换句话说,包装log4net避免耦合到它是一种反模式。
< / rant>
如果你觉得需要注入它,使你的记录器实例可以通过属性来访问,以启用注入,但创建一个默认实例的老式方式。
至于在每个日志消息中包含上下文状态,您需要添加一个全局属性,其ToString()解析到您要查找的内容。例如,对于当前堆大小:
public class TotalMemoryProperty { public override string ToString() { return GC.GetTotalMemory(false).ToString(); } }
然后在启动期间插入:
GlobalContext.Properties["TotalMemory"] = new TotalMemoryProperty();