Net6与NLog没有注册我的自定义渲染布局



在a中。Net6Webneneneba API使用NLog,我如何拦截发布的主体,以便在日志记录之前对其进行操作?

以下是我得到的:

我有一个。Net Framework 4.7.2 Web API,带有DelegatingHandler以拦截请求的主体。然后,我遍历每个键,如果该键在字符串列表中,则替换该值。例如:如果密钥是PasswordPwd,我会将该值替换为xxx,这样我就可以在没有安全问题的情况下记录全文。效果很好。我正试图在上复制这个。Net 6 Web API项目。

以下是我所做的:

我已经查看了NLog源代码,看看它们是如何获得aspnet-request-posted-body的。我相信我得到了一些东西,但我没有看到NLog调用/使用我的RenderLayout

[LayoutRenderer("aspnet-request-posted-body-2")]
public class TestRender : AspNetLayoutRendererBase {
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) {
var items = HttpContextAccessor.HttpContext?.Items;
if (items == null || items.Count == 0) {
return;
}
if (items.TryGetValue("aspnet-request-posted-body-2", out var value)) {
builder.Append(value as string);
}
}
}

我的Middleware

public class RequestLoggerMiddleware {
private readonly RequestDelegate _next;
private readonly ILogger<RequestLoggerMiddleware> _logger;
public RequestLoggerMiddleware(RequestDelegate next, ILogger<RequestLoggerMiddleware> logger) {
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context) {
var requestBody = await new HttpContextExtensions().PeekBodyAsync(context);
var contentType = context.Request.ContentType;
// Not done yet, but adding this for testing
switch (contentType) {
case "application/x-www-form-urlencoded":
// Clean data
...
// Add to context
context.Items.Add("aspnet-request-posted-body-2", requestBody);
break;
case "application/*+json":
case "application/json":
case "text/json":
// Clean data
...
// Add to context
context.Items.Add("aspnet-request-posted-body-2", JsonSerializer.Serialize(requestBody));
break;
default:
break;
}
_logger
.LogInformation("TESTING");

// With a breakpoint I checked that `content` does have the item listed above
await _next.Invoke(context);
}
}

这是我的Program.cs文件

var logger = LogManager
.LoadConfiguration(string.Concat(Directory.GetCurrentDirectory(), "/Configs/NLog/nlog.config"))
.Setup()
.SetupExtensions(x => {
x.RegisterLayoutRenderer<TestRender>("aspnet-request-posted-body-2");
})
.GetCurrentClassLogger();
logger.Debug("init main");
try {
var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Host.UseNLog();
var app = builder.Build();
// Register NLog's Request Body Layout
app.UseMiddleware<NLogRequestPostedBodyMiddleware>();
// Register my custom layout
app.UseMiddleware<RequestLoggerMiddleware>();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
} catch (Exception exception) {
logger.Error(exception, "Stopped program because of exception");
throw;
} finally {
LogManager.Shutdown();
}

当您将请求体存储在HttpContext.Items-字典中时,就不需要注册自定义布局。只需在NLog.config中使用${aspnet-item:aspnet-request-posted-body-2}即可。另请参阅:https://github.com/NLog/NLog/wiki/AspNet-HttpContext-Item-Layout-Renderer

也许可以考虑删除NLogRequestPostedBodyMiddleware,因为您已经有了自己的RequestLoggerMiddleware

Btw。请确保在加载依赖于这些扩展的日志记录配置之前连接SetupExtensions。示例LogManager.Setup().SetupExtensions(...).LoadConfigurationFromFile(string.Concat(Directory.GetCurrentDirectory(), "/Configs/NLog/nlog.config")

最新更新