Search code examples
c#postsharp

Custom PostSharp Logging


Using PostSharp for a C# application, I have the following scenario:

  • Namespace_A.CustomLoggingMethod
  • Namespace_B.DoSomethingMethod (in fact several different methods)

DoSomethingMethod makes a call to CustomLoggingMethod, which creates the log entry in the desired format and is working well. As expected, the log entry logs the source as CustomLoggingMethod, and I would prefer to override this to show the original calling method (e.g. DoSomethingMethod), which I can obtain from the stack. Does anyone know how I can achieve this for this one method?

As a follow-up is there a way I can also prevent the entry/exit log entries for my custom logging method only?


Solution

  • You can, but at the cost of some performance.

    The follow-up is easy: you annotate CustomLoggingMethod with [Log(AttributeExclude=false)] and it will no longer produce automatic logging of entry/exit.

    As for the main question, there are overloads for both LogSource.Get() and the .Write method on LogLevelSource where you can supply your own CallerInfo. The CallerInfo object contains both the type and the method name.

    What you could do is create the CallerInfo object in your custom method programatically and pass it to those methods. You can get the method name from [CallerMemberName] but you would need to pass the type as an argument.

    Or, as you said, you can obtain the type from the stack. You can do this most easily with CallerInfo.GetDynamic, but in my experience, this is slow. If you start logging thousands of lines per second, you will see a performance drop from walking the stack this way.

    Here's how the custom method could look like:

    [Log(AttributeExclude = true)]
    public static void CustomLogging(string message)
    {
      CallerInfo callerInfo = CallerInfo.GetDynamic(1);
      LogSource.Get(ref callerInfo).Warning.Write(FormattedMessageBuilder.Formatted(message), default, ref callerInfo);
    }
    

    Writing custom logging without using a custom method avoids the problem because PostSharp rewrites the custom logging call to include the information on the caller in the IL code.