Logging the AOP-way and custom messages

135 Views Asked by At

I am trying to implement logging capabilites into my application using Autofac's IInterceptor interface provided by Autofac.Extras.DynamicProxy. This is what I got so far.

A service which actions should get logged:

[Intercept("log-calls")]
public class FooService : IFooService
{
    public int Add(int lhs, int rhs)
    {
        return lhs + rhs;
    }
}

My IInterceptor implementation:

public class Logger : IInterceptor
{
    private readonly ILogger logger;

    public Logger(ILogger logger)
    {
        this.logger = logger;
    }

    public void Intercept(IInvocation invocation)
    {
        var name = $"{invocation.Method.DeclaringType}.{invocation.Method.Name}";
        var args = string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()));

        this.logger.Write($"Calling: {name}");
        this.logger.Write($"Args: {args}");

        var watch = Stopwatch.StartNew();
        invocation.Proceed();
        watch.Stop();

        var executionTime = watch.ElapsedMilliseconds;

        this.logger.Write($"Done: result was {invocation.ReturnValue}");
        this.logger.Write($"Execution Time: {executionTime}ms");
    }
}

A test showing it's usage:

[Fact]
public void Should_Intercept_Method_Call()
{
    // Arrange
    var builder = new ContainerBuilder();

    // ITestOutputhelper instance in this case
    builder.Register(c => new Logger(this.logger)) 
        .Named<IInterceptor>("log-calls");

    builder.RegisterType<FooService>()
        .As<IFooService>()
        .EnableInterfaceInterceptors();

    var container = builder.Build();

    using var scope = container.BeginLifetimeScope();

    var service = scope.Resolve<IFooService>();

    // Act
    _ = service.Add(2, 3);

    // ...
}

Result:

Calling: ClassLibrary1.IFooService.Add
Args: 2, 3
Done: result was 5
Execution Time: 0ms

I am used to output messages (to debug console and textfile) that shows me what is going on in my application. Things like "SomeService has exported 42 items" or "AnotherService has finished reading 20 items to the database" and so on.

Now I am wondering how I could mimic this behavior without having to inject my ILogger instance again everywhere. The AOP-way of logging is kind a static in terms of messages we can provide.

I hope its clear what I am trying to achieve.

1

There are 1 best solutions below

0
On

if your want to no [Intercept("log-calls")] on class, you can try runtime aop framework like Norns.Urd or others which provide GlobalInterceptor

you just need add LoggerInterceptor once, like this:

public void ConfigureServices(IServiceCollection services)
{
    services.ConfigureAop(i => i.GlobalInterceptors.Add(new LoggerInterceptor()));
}