我想记录方法入口并使用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方法调用BusinessLayerClass中的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(“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);
}
}