使用NLog在.NET中记录方法的进入和退出
我想记录方法入口并使用NLog退出。 我发现了两种方法。 第一个,使用PostSharp,但需要购买。 第二种方法,使用unity,但我们只能在具有接口的方法上实现它。
例如,我有一个名为SampleController的控制器
SampleController.cs
public string Get() { BusinessLayerClass businessLayer = new BusinessLayerClass(); return businessLayer.BusinessLayerMethod(); }
BusinessLayerClass.cs
public class BusinessLayerClass { public string BusinessLayerMethod() { DataLayerClass dataLayerClass = new DataLayerClass(); return dataLayerClass.DataLayerMethod(); } }
DataLayerClass.cs
public class DataLayerClass { public string DataLayerMethod() { return "Hi"; } }
我在示例控制器中有两个类BusinessLayerClass
和DataLayerClass.Get
方法,在BusinessLayerMethod
中调用BusinessLayerMethod
,并从中调用DataLayerMethod
。 我有一个NLogging
类用于记录目的
NLogging.cs
public static class NLogging { public static bool Enabled { get { return LogManager.IsLoggingEnabled(); } set { if (value) { while (!Enabled) LogManager.EnableLogging(); } else { while (Enabled) LogManager.DisableLogging(); } } } public static void Fatal(string message, Exception exception = null, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMember = "", [CallerLineNumber] int callerLine = 0) { Log(LogLevel.Fatal, message, exception, callerPath, callerMember, callerLine); } public static void Trace(string message, Exception exception = null, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMember = "", [CallerLineNumber] int callerLine = 0) { Log(LogLevel.Trace, message, exception, callerPath, callerMember, callerLine); } public static void Debug(string message, Exception exception = null, [CallerFilePathAttribute] string callerPath = "", [CallerMemberName] string callerMember = "", [CallerLineNumber] int callerLine = 0) { Log(LogLevel.Debug, message, exception, callerPath, callerMember, callerLine); } public static void Info(string message, Exception exception = null, [CallerFilePathAttribute] string callerPath = "", [CallerMemberName] string callerMember = "", [CallerLineNumber] int callerLine = 0) { Log(LogLevel.Info, message, exception, callerPath, callerMember, callerLine); } public static void Warn(string message, Exception exception = null, [CallerFilePathAttribute] string callerPath = "", [CallerMemberName] string callerMember = "", [CallerLineNumber] int callerLine = 0) { Log(LogLevel.Warn, message, exception, callerPath, callerMember, callerLine); } public static void Error(string message, Exception exception = null, [CallerFilePathAttribute] string callerPath = "", [CallerMemberName] string callerMember = "", [CallerLineNumber] int callerLine = 0) { Log(LogLevel.Error, message, exception, callerPath, callerMember, callerLine); } private static void Log(LogLevel level, string message, Exception exception = null, string callerPath = "", string callerMember = "", int callerLine = 0) { LogManager.ThrowExceptions = true; var logger = LogManager.GetLogger(callerPath); if (!logger.IsEnabled(level)) return; var logEvent = new LogEventInfo(level, callerPath, message) { Exception = exception }; logEvent.Properties.Add("callerpath", callerPath); logEvent.Properties.Add("callermember", callerMember); logEvent.Properties.Add("callerline", callerLine); logger.Log(logEvent); } }
我不能在这里使用Unity ,因为BusinessLayerClass
和DataLayerClass
不实现接口。
在每种方法中调用NLogging.Trace(methodname)
都会NLogging.Trace(methodname)
方便。 例如,如果我更改我的方法名称,我还需要更改日志记录代码,如NLogging.Trace("Entered into ModifiedBusinessLayerMethod")
。
有没有其他方法来记录方法进入和退出而不使用这两种方法?
您可以使用Fody和MethodDecorator.Fody加载项。 Fody是一个免费的开源代码编织库。
如何设置:
1.安装包
PM> Install-Package MethodDecorator.Fody
2.装饰方法
public class BusinessLayerClass { [LogMethod] public string BusinessLayerMethod() { DataLayerClass dataLayerClass = new DataLayerClass(); return dataLayerClass.DataLayerMethod(); } }
3.编写拦截器
using System; using System.Reflection; [module: LogMethod] // Atribute should be "registered" by adding as module or assembly custom attribute // Any attribute which provides OnEntry/OnExit/OnException with proper args [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Assembly | AttributeTargets.Module)] public class LogMethodAttribute : Attribute, IMethodDecorator { private MethodBase _method; // instance, method and args can be captured here and stored in attribute instance fields // for future usage in OnEntry/OnExit/OnException public void Init(object instance, MethodBase method, object[] args) { _method = method; } public void OnEntry() { NLogging.Trace("Entering into {0}", _method.Name); } public void OnExit() { NLogging.Trace("Exiting into {0}", _method.Name); } public void OnException(Exception exception) { NLogging.Trace(exception, "Exception {0}", _method.Name); } }