I'd like to use the Log PostSharp aspect in order to easily log all entry and exit values of my async Web API end points.
For example:
[Log]
[HttpGet]
public async Task<List<string>> Get(List<int> ids)
{
var result = await GetResult(ids);
return result;
}
The result is:
DEBUG Controllers.MyController - Entering: MyController.Get(this = {Controllers.MyController}) :
{System.Collections.Generic.List`1[System.String]}
DEBUG Controllers.MyController - Leaving: MyController.Get(this = {Controllers.MyController}) :
{System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[System.String]]}
Instead of the actual values. How could I achieve this?
Log aspect doesn't support async methods in PostSharp 4.3 and older versions. You can easily develop your own custom logging aspect:
[PSerializable]
public sealed class CustomLog : OnMethodBoundaryAspect
{
public CustomLog()
{
ApplyToStateMachine = true;
}
public override void OnSuccess(MethodExecutionArgs args)
{
var stringBuilder = new StringBuilder();
var declaringType = args.Method.DeclaringType;
stringBuilder.Append("Exiting ");
stringBuilder.Append(declaringType.FullName);
stringBuilder.Append('.');
stringBuilder.Append(args.Method.Name);
if (!args.Method.IsConstructor && ((MethodInfo) args.Method).ReturnType != typeof(void))
{
stringBuilder.Append(" with return value ");
stringBuilder.Append(args.ReturnValue);
}
Logger.WriteLine(stringBuilder.ToString());
}
}
The important thing is in constructor: ApplyToStateMachine = true
instructs PostSharp to properly apply the aspect to state machines (async methods and enumerators). Without ApplyToStateMachine = true
would CustomLog behave in the same way as standard Log aspect does.
This example doesn't work with generic methods and types, doesn't work well with more complex argument and return types and has many other limitations.
You can find more complete solution in this PostSharp sample: CustomLogging. Unfortunately the example doesn't contain any information about ApplyToStateMachine = true
.
EDIT 11/04/2016:
This example is working in PostSharp 5.0.10 even for async methods. args.ReturnValue
contains the return value of an async method.