在ASP.NET核心(.NET5)中,如何在单独的文件上为每个请求编写日志?使用序列号或其他



我是.NET和Web服务开发的新手,所以我不确定如何实现我的需求。

  • 我的Web服务收到一个包含一些数据的POST请求,我需要生成pdf文件的过程:name_YYYYMMDDHmmss.pdf
  • 为了监控这一点,我希望为每个请求都有一个单独的日志文件,其名称与输出文件类似:name_YYYYMMDDHMMss.log
  • 我希望避免将配置对象传递到每个需要向日志文件添加内容的类/函数中

我已经安装了Serilog,它可以满足我的需求,但当我收到并发请求时就不行了。我也不完全确定在.NET中如何处理同时请求(到目前为止,我还没有编写特定于线程的代码(,但据我所知,当我更改全局记录器文件名时,该对象在所有线程之间共享,因此所有线程都写入同一个文件。

我已经研究了很多解决方案,但我没有找到适合这一点的解决方案,而且似乎大多数人都把所有东西都放在一个文件中。。。

你能给我什么线索吗?我对使用Serilog以外的其他东西持开放态度。

基于特定上下文的动态文件名的一种方法是使用Serilog.Sinks.Map,然后通过请求管道中的中间件,可以向日志上下文添加一个属性,该属性驱动在写入日志时使用的文件名。

Serial.Sinks.Map用于决定运行时使用哪个文件名的类似用法示例:

  • Serilog-无法根据属性登录到多个文件
  • 在Serilog中动态更改日志文件路径

我发现这个问题的最佳解决方案是使用Serial.Sinks.Map

Log.Logger = new LoggerConfiguration()
.WriteTo.Map("Name", "Default", (name, wt) => {
var fileName = name == "Default" ? "log" : $"{log-{name}}" 
wt.File($"./{fileName}-.txt");
}).CreateLogger();

然后在我的控制器上,在我需要这个功能的每个方法上,我将所有指令都包含在一个LongContext中,如下所示:

[HttpGet]
public IHttpActionResult Get() {
using (LogContext.PushProperty("Name", "theFileName") {
// ...
_myService.Method1();
// ...
}
}
public class MyService : IMyService {
// ...
public void Method1() {
// ...
Log.Information("This is what happened at this point…");
// ...
}
// ...
}

因此,内部的所有Log都将使用该上下文,并使用您为该上下文设置的名称在另一个文件上进行写入,而无需修改代码中已经存在的任何Log.Information/Error/Warning/etc。这是丑陋的部分。。。您必须在根位置定义一个上下文,以便使这些日志写入不同的文件。因此,对于一个控制器方法,您必须做的第一件事是用LogContext将其全部封装起来。

最新更新