Search code examples
asp.net-coreserilog

Can Serilog return the value of resulting action rather than the data type?


I have Serilog in a .net core 2.1 web API using the Serilog.AspNetCore package. When an action gets called the incoming parameters are logged:

[INF] Executing action method WebApi.Controllers.ValuesController.Get (WebApi) with arguments (["4"]) - Validation state: "Valid"

But when the action is done I get the following less useful lines:

[INF] Executed action method WebApi.Controllers.ValuesController.Get (WebApi), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 8.2537ms.
[INF] Executing ObjectResult, writing value of type 'System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]'.

I'd prefer the actual values. For example, the Dictionary should just be json.

Is there a way to override this default behavior?


Solution

  • For Serilog, it could return json data type, but, you could not change the built-in return value for Executing ObjectResult. This is controlled by ObjectResultExecuting, and this is hard-code.

    public static void ObjectResultExecuting(this ILogger logger, object value)
    {
        if (logger.IsEnabled(LogLevel.Information))
        {
            var type = value == null ? "null" : value.GetType().FullName;
            _objectResultExecuting(logger, type, null);
        }
    }
    

    ObjectResultExecuting logs the type instead of the value. I assume it is for better performance. You could assume that if you serialize the response to string, it will waste a lot performance, and there is no need for that.

    If you prefer to log the specific response, you may try to log in the method by yourself.

    [Produces("application/json")]
    [Route("api/[controller]")]
    public class SerilogController : Controller
    {
        private readonly ILogger<SerilogController> _log;
        public SerilogController(ILogger<SerilogController> log)
        {
            _log = log;
        }
    
        [HttpGet]
        public IEnumerable<string> Get(string password)
        {
            _log.LogInformation(JsonConvert.SerializeObject(new string[] { "value1", "value2" }));
            return new string[] { "value1", "value2" };
        }
    }