Search code examples
c#asp.net-mvcaoppostsharpserilog

How to use postsharp with Serilog to separate logging aspect?


I'm a beginner to AOP and I try to use PostSharp with SeriLog to log my MVC application.

So I find this sample example as a start, but I wonder If in this example it uses the logger explicitly like that:

activity.Write(LogLevel.Warning, "The entity {id} has been marked for deletion.", item.Id);

in a business class QueueProcessor, Then what's the value of aspect here! I still write logging code coupled with business code!.


Could someone help me to separate the logging out of the MVC project using PostSharp.Patterns.Diagnostics.Backends.Serilog?


Solution

  • You are misunderstanding the example, let me clearify.

    There are two kinds of logging in the sample code. You found the obvious one, activity.Write(xxx). This kind of logging is not covered by using an AOP framework like PostSharp. This kind of logging can be seen as part of the business logic as it is specific to the actions that are taking place.

    Now, on the other hand: let's assume you want to log each and every call to all methods in your application. You want to log when the method is called and with what parameters. Also, you want to log the returned value, if any.

    Imaging having to write something like this for every method:

    bool SomeMethod(int input)
    {
        var sw = Stopwatch.StartNew();
        logger.Write($"Started executing {nameof(SomeMethod)} at {DateTime.Now}. Value of {nameof(input)}: {input})";
    
        ... // some work
        var returnValue = false;
    
        sw.Stop();
        logger.Write($"Finished executing {nameof(SomeMethod)}. It took {sw.ElapsedMilliseconds}ms. Returned value: {returnValue}");
    
        return returnValue;
    }
    

    Now that is a cross cutting concern and that is what the example demonstrates. This plumbing code is injected by PostSharp by just doing this in program.cs:

    using PostSharp.Patterns.Diagnostics;
    using PostSharp.Patterns.Diagnostics.Backends.Serilog;
    using PostSharp.Samples.Logging.BusinessLogic;
    using Serilog;
    
    // Add logging to all methods of this project.
    [assembly: Log]
        ...
    

    More details here

    Now, at the end, let's go back to your question:

    Could someone help me to separate the logging out of the MVC project using PostSharp.Patterns.Diagnostics.Backends.Serilog?

    I am not sure what you expect from any AOP framework regarding custom logging inside business logic code. Could you expand on this? Or is the above clarification enough?

    Edit: addressing the issues from your comment

    1. I do not think the example of PostSharp is a DDD example. They merely demonstrate that the logger used for the aspect can also be used to log business related information (Entity is marked for deletion.) In DDD if this information is relevant to someone or something it would be an event that could be logged using an aspect.
    2. Creating an audit trail by using auditing aspects for capturing the events is certainly the right way to do that. As to the presentation layer, you could use some middleware to log requests and responses like demonstrated here for example. In that case there is no need to use PostSharp. Depending on your eventing code in your DDD application you might be able to intercept events as well before or after they are send so you can write your own logging there as well, removing the need for PostSharp.
    3. Did you try the steps listened in the answers of the question that has been marked as the duplicate?