简体   繁体   中英

c# Asp.Net Core Serilog RequestLoggingMiddleware

I was trying to carry out tests with the Serilog middleware to log the API calls, during the tests they managed to get the following log:

{
    "@mt": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
    "@r": ["8712.8264"],
    "@t": "2021-03-22T09:55:36.2043022Z",
    "ActionId": "75bdfbf6-3da7-4827-9969-eda23053edf9",
    "ActionName": "WebAPI.Controllers.v1.UserController.Login (WebAPI)",
    "ContentType": null,
    "Elapsed": 8712.8264,
    "EndpointName": "WebAPI.Controllers.v1.UserController.Login (WebAPI)",
    "Host": "localhost:44369",
    "Protocol": "HTTP/1.1",
    "RequestId": "80000002-0002-fb00-b63f-84710c7967bb",
    "RequestMethod": "POST",
    "RequestPath": "/api/v1/User/Login",
    "Scheme": "https",
    "SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
    "StatusCode": 200,
    "request": {
        "$type": "LoginRequest",
        "Email": "email@test.it",
        "Password": "********"
    }
}

which combines the information of the httpcontext plus the serialization of the request body that I had made in the controller like this:

[HttpPost(nameof(Login))]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> Login([FromBody]LoginRequest request)
{
    var requestClone = request.DeepClone();
    requestClone.Password = "********";

    _logger.LogInformation("{@request}", requestClone);
    
    var user = await _userManager.FindByEmailAsync(request.Email);
    ...

}

this is the middleware registration in Startup Configure:

......
app.UseSerilogRequestLogging(options =>
{
    options.EnrichDiagnosticContext = LogHelper.EnrichFromRequest;
});

app.UseRouting();
.... 

and this is the LogHelper.EnrichFromRequest:

public class LogHelper
{
    public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
    {
        var request = httpContext.Request;

        diagnosticContext.Set("Host", request.Host);
        diagnosticContext.Set("Protocol", request.Protocol);
        diagnosticContext.Set("Scheme", request.Scheme);

        var endpoint = httpContext.GetEndpoint();

        if (endpoint is not null)
        {
            diagnosticContext.Set("EndpointName", endpoint.DisplayName);
        }

        if(request.QueryString.HasValue)
        {
            diagnosticContext.Set("QueryString", request.QueryString.Value);
        }

        diagnosticContext.Set("ContentType", httpContext.Response.ContentType);
    }
}

The problem is that I have made some changes and I can no longer get a log like the previous one. Where am I wrong, I just can't understand how it worked this morning and now it doesn't. Please help me?
Thanks

UPDATE

this is serilog cofiguration:

"Serilog": {
"MinimumLevel": {
  "Default": "Information",
  "Override": {
    "Microsoft": "Warning",
    "System": "Warning",
    "IdentityServer4" : "Debug" 
  }
},
"WriteTo": [
  {
    "Name": "Async",
    "Args": {
      "bufferSize": 1,
      "blockWhenFull": true,
      "configure": [
        {
          "Name": "Logger",
          "Args": {
            "configureLogger": {
              "Filter": [
                {
                  "Name": "ByIncludingOnly",
                  "Args": {
                    "expression": "Contains(SourceContext, 'WebAPI') or Contains(SourceContext, 'Serilog.AspNetCore.RequestLoggingMiddleware')"
                  }
                }
              ],
              "WriteTo": [
                {
                  "Name": "File",
                  "Args": {
                    "path": "%BASEDIR%/logs/AuthN/log-.log",
                    "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
                    "rollingInterval": "Day",
                    "retainedFileCountLimit": "7",
                    "buffered" : false 
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
],
"Enrich": [ "FromLogContext" ]

}

eventually, I was able to create the log posted above by simply injecting IDiagnosticContext into the controller instead of ILogger and replacing this:

_logger.LogInformation("{@request}", requestClone);

with this:

_diagnosticContext.Set("Request", requestClone, true);

I know that in doing so I have a strong dependency between the controller and serilog, but I don't see other solutions.
Hope it will be useful to someone who has encountered the same problem.
Thank you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM