문제

나는 애플리케이션 메서드 로깅의 부담을 덜기 위해 Postsharp 프레임워크를 사용하는 것을 고려하고 있습니다.기본적으로 로깅 속성으로 메소드를 장식할 수 있으며 컴파일 타임에 필요한 로깅 코드를 il에 삽입합니다.저는 이 솔루션이 타임 코드 환경에서 소음을 제거하는 것을 좋아합니다.어떤 생각, 경험 또는 더 나은 대안이 있습니까?

도움이 되었습니까?

해결책

Castle Windsor DynamicProxies를 사용하여 AOP로 로깅을 적용합니다.저는 이미 IoC 컨테이너로 Castle을 사용하고 있었기 때문에 AOP에 Castle을 사용하는 것이 저에게는 저항이 가장 적은 경로였습니다.더 많은 정보를 원하시면 알려주세요. 블로그 게시물로 공개하기 위해 코드를 정리하는 중입니다.

편집하다

좋아, 여기에 기본 인터셉터 코드가 있습니다. 매우 기본적이지만 필요한 모든 작업을 수행합니다.두 개의 인터셉터가 있는데, 하나는 모든 것을 기록하고 다른 하나는 메소드 이름을 정의하여 보다 세부적인 로깅을 허용합니다.이 솔루션은 Castle Windsor에 매우 의존적입니다.

추상 기본 클래스

namespace Tools.CastleWindsor.Interceptors
{
using System;
using System.Text;
using Castle.Core.Interceptor;
using Castle.Core.Logging;

public abstract class AbstractLoggingInterceptor : IInterceptor
{
    protected readonly ILoggerFactory logFactory;

    protected AbstractLoggingInterceptor(ILoggerFactory logFactory)
    {
        this.logFactory = logFactory;
    }

    public virtual void Intercept(IInvocation invocation)
    {
        ILogger logger = logFactory.Create(invocation.TargetType);

        try
        {
            StringBuilder sb = null;

            if (logger.IsDebugEnabled)
            {
                sb = new StringBuilder(invocation.TargetType.FullName).AppendFormat(".{0}(", invocation.Method);

                for (int i = 0; i < invocation.Arguments.Length; i++)
                {
                    if (i > 0)
                        sb.Append(", ");

                    sb.Append(invocation.Arguments[i]);
                }

                sb.Append(")");

                logger.Debug(sb.ToString());
            }

            invocation.Proceed();

            if (logger.IsDebugEnabled && invocation.ReturnValue != null)
            {
                logger.Debug("Result of " + sb + " is: " + invocation.ReturnValue);
            }
        }
        catch (Exception e)
        {
            logger.Error(string.Empty, e);
            throw;
        }
    }
}
}

전체 로깅 구현

namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Logging;

public class LoggingInterceptor : AbstractLoggingInterceptor
{
    public LoggingInterceptor(ILoggerFactory logFactory) : base(logFactory)
    {
    }
}
}

메소드 로깅

namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Interceptor;
using Castle.Core.Logging;
using System.Linq;

public class MethodLoggingInterceptor : AbstractLoggingInterceptor
{
    private readonly string[] methodNames;

    public MethodLoggingInterceptor(string[] methodNames, ILoggerFactory logFactory) : base(logFactory)
    {
        this.methodNames = methodNames;
    }

    public override void Intercept(IInvocation invocation)
    {
        if ( methodNames.Contains(invocation.Method.Name) )
            base.Intercept(invocation);
    }
}
}

다른 팁

포스트샤프에 +1.C# 코드에 전제조건과 사후조건을 추가하려는 시도를 포함하여 여러 가지 용도로 사용해 왔지만 그것 없이는 어떻게 만들 수 있을지 모르겠습니다...

이는 프로젝트를 얼마나 오랫동안 개발하고 지원할 것인지에 따라 달라집니다.물론, IL 위빙은 좋은 기술이지만 IL 및/또는 어셈블리 메타데이터 형식이 다시 변경되고(1.1에서 2.0 사이에서 그랬던 것처럼) 이러한 변경으로 인해 도구가 새 형식과 호환되지 않게 되면 어떻게 될까요?

도구에 의존한다면 도구가 지원할 때까지 기술을 업그레이드할 수 없습니다.이에 대한 보장이 없으면(또는 개발이 계속될 것 같지만) 장기 프로젝트에서 사용하는 것에 대해 매우 조심할 것입니다.

단기적으로는 문제가 되지 않습니다.

정확히 이 작업을 수행하는 데 사용되었습니다.훌륭하게 작동합니다!나는 그것을 강력히 추천합니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top