[英]c# Asp.Net Core Serilog RequestLoggingMiddleware
我試圖使用 Serilog 中間件進行測試以記錄 API 調用,在測試期間他們設法獲得以下日志:
{
"@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": "********"
}
}
它結合了 httpcontext 的信息加上我在 controller 中所做的請求正文的序列化,如下所示:
[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);
...
}
這是 Startup Configure 中的中間件注冊:
......
app.UseSerilogRequestLogging(options =>
{
options.EnrichDiagnosticContext = LogHelper.EnrichFromRequest;
});
app.UseRouting();
....
這是 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);
}
}
問題是我做了一些更改,我不能再像以前那樣得到日志。 我哪里錯了,我只是不明白今天早上它是如何工作的,現在它沒有。 請幫我?
謝謝
更新
這是 serilog 配置:
"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" ]
}
最終,我能夠通過簡單地將 IDiagnosticContext 注入 controller 而不是 ILogger 並替換它來創建上面發布的日志:
_logger.LogInformation("{@request}", requestClone);
有了這個:
_diagnosticContext.Set("Request", requestClone, true);
我知道這樣做我在 controller 和 serilog 之間有很強的依賴關系,但我沒有看到其他解決方案。
希望對遇到同樣問題的人有用。
謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.