PostSharp和Common.Logging Logger声明

时间:2013-09-05 15:02:22

标签: postsharp common.logging

我正在使用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
}

1 个答案:

答案 0 :(得分:2)

初始化记录器_log实例的正确位置是RuntimeInitialize方法。在当前示例中,仅在编译期间创建记录器。

我还建议为每个_stopwatch初始化OnEntry的新实例不是线程安全的,可能会导致错误的结果。

您可以使用静态秒表和MethodExecutionArgs.MethodExecutionTag属性将当前时间存储在OnEntry中。之后,此值将传递到您的OnSuccessOnExit方法。

因此修改后的示例可能如下所示:

[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
}