对于大名顶顶的Log4Net大家一定都很熟悉。在项目应用中,往往会对 Log4Net 进行二次包装以满足项目的特殊需求。比如自动记录调用 Log 方法的调用方法名,类名。
利用 System.Diagnostics.StackTrace 来了解哪个方法调用了该方法(以及哪个方法调用了其调用者,等等)。从其名称可以看出,StackTrace 对象跟踪等待当前过程完成的所有悬挂过程。可以采用许多方式创建 StackTrace 对象。在其最简单方式中,不向其构造函数传递参数, 并取得作为一组 StackFrame 对象的完整堆栈映像, 可以按其索引进行列举。
'Enumerateallthestackframeobjects.
'Theframeatindex0correspondstothecurrentroutine.
ForiAsInteger=0Tost.FrameCount-1
'Gettheithstackframeandprintthemethodname.
DimsfAsStackFrame=st.GetFrame(i)
Console.WriteLine(sf.GetMethod().Name)
Next
于是自定义一个Log4Net的包装类, 利用 StackTrace 来获得Log4Net包装类的调用类名和调用方法名:
Importslog4net
ImportsSystem.Runtime.CompilerServices
ImportsSystem.Diagnostics

PublicClassLoggerClassLogger

PrivateSubNew()SubNew()
EndSub
PrivateSharedlogAsILog=LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

SharedSubNew()SubNew()
LoggerConfig.Config()
EndSub
<MethodImpl(MethodImplOptions.NoInlining)>_
PrivateSharedFunctionFormatMessage()FunctionFormatMessage(ByValmessageAsString)
DimstAsStackTrace=NewStackTrace()
DimsfAsStackFrame=st.GetFrame(2)
ReturnString.Format("{0}.{1}:{2}",sf.GetMethod().DeclaringType.Name,_
sf.GetMethod().Name,message)
EndFunction

PublicSharedSubLogDebug()SubLogDebug(ByValmessageAsString)
Iflog.IsDebugEnabledThen
log.Debug(FormatMessage(message))
EndIf
EndSub

PublicSharedSubLogInfo()SubLogInfo(ByValmessageAsString)
Iflog.IsInfoEnabledThen
log.Info(FormatMessage(message))
EndIf
EndSub

PublicSharedSubLogWarn()SubLogWarn(ByValmessageAsString)
Iflog.IsWarnEnabledThen
log.Warn(FormatMessage(message))
EndIf
EndSub

PublicSharedSubLogError()SubLogError(ByValmessageAsString)
Iflog.IsErrorEnabledThen
log.Error(FormatMessage(message))
EndIf
EndSub

PublicSharedSubLogFatal()SubLogFatal(ByValmessageAsString)
Iflog.IsFatalEnabledThen
log.Fatal(FormatMessage(message))
EndIf
EndSub
EndClass
例子:

PublicClassForm1ClassForm1

PrivateSubButton1_Click()SubButton1_Click(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesButton1.Click
Logger.LogInfo("Entering")
CallTest()
Logger.LogInfo("Exiting")
EndSub

PrivateSubCallTest()SubCallTest()
Logger.LogInfo("Entering")
Logger.LogInfo("Exiting")
EndSub
EndClass
打印日志如下:
2007-02-25 20:38:27,000 [5692] INFO - Form1.Button1_Click: Entering
2007-02-25 20:38:27,015 [5692] INFO - Form1.CallTest: Entering
2007-02-25 20:38:27,015 [5692] INFO - Form1.CallTest: Exiting
2007-02-25 20:38:27,015 [5692] INFO - Form1.Button1_Click: Exiting
红色字体部分就是通过StackFrame增加的信息。通过这种机制,可以使得Logger使用更简单,信息更丰富。是不是很棒?
本文介绍了一种增强Log4Net日志记录的方法,通过利用System.Diagnostics.StackTrace获取调用类名和方法名,使日志信息更加丰富。文章提供了一个VB.NET实现的例子。
7538

被折叠的 条评论
为什么被折叠?



