我正在使用OnMethodBoundryAspect创建一个简单的日志记录和执行时序方面。我想为每个方法创建一个记录器。但是,如果Logger未声明为静态成员,则它不起作用。如果它被声明为静态,则不可能为每个方法创建一个记录器。
这是我的方面:
[Serializable]
public class MonitorAttribute : OnMethodBoundaryAspect
{
[NonSerialized]
private Stopwatch _stopwatch;
private string _methodName;
private ILog _log;
public MonitorAttribute()
{
}
/// <summary>
/// overrides the method name in the logs
/// </summary>
/// <param name="method"></param>
public MonitorAttribute(string method)
{
_methodName = method;
}
#region Overrides
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
if (string.IsNullOrEmpty(_methodName))
_methodName = method.Name;
_log = LogManager.GetLogger(_methodName);
}
public override void OnEntry(MethodExecutionArgs args)
{
_stopwatch = Stopwatch.StartNew();
_log.InfoFormat("Method {0} called", _methodName);
}
public override void OnExit(MethodExecutionArgs args)
{
_stopwatch.Stop();
_log.InfoFormat("Method {0} exited successfully. execution time {1} milliseconds", _methodName, _stopwatch.ElapsedMilliseconds);
}
public override void OnSuccess(MethodExecutionArgs args)
{
_stopwatch.Stop();
_log.InfoFormat("Method {0} executed successfully. execution time {1} milliseconds", _methodName, _stopwatch.ElapsedMilliseconds);
}
#endregion
}
答案 0 :(得分:2)
初始化记录器_log
实例的正确位置是RuntimeInitialize
方法。在当前示例中,仅在编译期间创建记录器。
我还建议为每个_stopwatch
初始化OnEntry
的新实例不是线程安全的,可能会导致错误的结果。
您可以使用静态秒表和MethodExecutionArgs.MethodExecutionTag属性将当前时间存储在OnEntry
中。之后,此值将传递到您的OnSuccess
和OnExit
方法。
因此修改后的示例可能如下所示:
[Serializable]
public class MonitorAttribute : OnMethodBoundaryAspect
{
private static Stopwatch _stopwatch = Stopwatch.StartNew();
[NonSerialized] private ILog _log;
private string _methodName;
public MonitorAttribute()
{
}
/// <summary>
/// overrides the method name in the logs
/// </summary>
/// <param name="method"></param>
public MonitorAttribute(string method)
{
_methodName = method;
}
#region Overrides
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
if (string.IsNullOrEmpty(_methodName))
_methodName = method.Name;
}
public override void RuntimeInitialize(MethodBase method)
{
_log = LogManager.GetLogger(_methodName);
}
public override void OnEntry(MethodExecutionArgs args)
{
_log.InfoFormat("Method {0} called", _methodName);
args.MethodExecutionTag = _stopwatch.ElapsedMilliseconds;
}
public override void OnExit(MethodExecutionArgs args)
{
long stopwatchStart = (long) args.MethodExecutionTag;
_log.InfoFormat("Method {0} exited successfully. execution time {1} milliseconds", _methodName,
_stopwatch.ElapsedMilliseconds - stopwatchStart);
}
public override void OnSuccess(MethodExecutionArgs args)
{
long stopwatchStart = (long) args.MethodExecutionTag;
_log.InfoFormat("Method {0} executed successfully. execution time {1} milliseconds", _methodName,
_stopwatch.ElapsedMilliseconds - stopwatchStart);
}
#endregion
}