在使用.Net 6 NLog的Web中,我如何拦截发布的主体,以便在记录它之前对其进行操作?
,这是我得到的:
我有一个.Net框架4.7.2WebAPI和一个DelegatingHandler
来拦截请求的主体。然后,我遍历每个键,如果键位于字符串列表中,则替换该值。例如:如果键是Password
或Pwd
,则将值替换为xxx
,这样就可以在不考虑安全性的情况下记录全文。效果很好。我正在尝试在一个.Net 6 Web项目上复制这一点。
,这是我所做的:
我已经通过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();
}
发布于 2022-09-16 05:06:04
当您将请求体存储在HttpContext.Items
-dictionary中时,不需要注册自定义布局。只需在${aspnet-item:aspnet-request-posted-body-2}
中使用NLog.config
即可。另见:https://github.com/NLog/NLog/wiki/AspNet-HttpContext-Item-Layout-Renderer
也许可以考虑删除NLogRequestPostedBodyMiddleware
,因为您已经有了自己的RequestLoggerMiddleware
。
顺便说一句。在加载依赖于这些扩展的日志配置之前,请确保连接SetupExtensions
。例如。LogManager.Setup().SetupExtensions(...).LoadConfigurationFromFile(string.Concat(Directory.GetCurrentDirectory(), "/Configs/NLog/nlog.config")
https://stackoverflow.com/questions/73733414
复制相似问题