mal*_*owa 5 logging scope asp.net-core-mvc asp.net-core
我读到MVC中间件框架内部使用带有控制器操作的日志范围:
谨慎使用范围,仅适用于有界限开始和结束的操作.例如,框架提供了围绕MVC操作的范围.避免将许多范围嵌套在一起.
和
范围是通过调用ILogger.BeginScope方法返回的IDisposable类型,该方法从创建它到处理它的那一刻持续.任何日志记录状态(例如事务标识)在创建范围时附加到范围.
我正在尝试使用此功能来编写一些日志信息.我执行了以下步骤:
1)创建Asp.net核心MVC应用
2)在appsetting.json中将属性"IncludeScopes"设置为"true"
3)创建控制器和动作,如下所示:
[Route("api/[controller]")]
public class TodoController : Controller
{
private readonly ILogger<TodoController> _logger;
public TodoController(ILogger<TodoController> logger)
{
_logger = logger;
}
// GET: api/values
[HttpGet]
public IEnumerable<string> Get()
{
_logger.LogInformation(1000, "Listing all items started");
Thread.Sleep(2000);
_logger.LogInformation(1000, "Listing all items finished");
return new string[] { "value1", "value2" };
}
}
Run Code Online (Sandbox Code Playgroud)
我希望我的日志消息流始终只包含"列出所有项目已启动"和"列出所有已完成的项目"部分,这些部分彼此不相互分离.但当我在同一时间启动两个请求时,得到的日志流如下:
RequestId:xxx列出所有项目已启动
RequestId:yyy列出所有项目已启动
RequestId:xxx列出所有项目已完成
RequestId:yyy列出所有项目已完成
什么原因?这是正确的行为,我在记录的背景下误解了"范围"一词吗?
日志记录范围有助于创建范围,在该范围内创建的任何日志语句都将具有可用的信息。
以下是来自ConsoleLogger设置IncludeScopes为true:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
=> RequestId:0HKT6JC0EVFNA RequestPath:/api/values
Request starting HTTP/1.1 GET http://localhost:5000/api/values
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
=> RequestId:0HKT6JC0EVFNA RequestPath:/api/values => WebApplication8.Controllers.ValuesController.Get (WebApplication8)
Executing action method WebApplication8.Controllers.ValuesController.Get (WebApplication8) with arguments () - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor[1]
=> RequestId:0HKT6JC0EVFNA RequestPath:/api/values => WebApplication8.Controllers.ValuesController.Get (WebApplication8)
Executing ObjectResult, writing value Microsoft.AspNetCore.Mvc.ControllerContext.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
=> RequestId:0HKT6JC0EVFNA RequestPath:/api/values => WebApplication8.Controllers.ValuesController.Get (WebApplication8)
Executed action WebApplication8.Controllers.ValuesController.Get (WebApplication8) in 322.8533ms
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
=> RequestId:0HKT6JC0EVFNA RequestPath:/api/values
Request finished in 428.477ms 200 application/json; charset=utf-8
Run Code Online (Sandbox Code Playgroud)
如果您注意到上面的日志,这里RequestId:0HKT6JC0EVFNA会为每个日志语句打印(如前所述,范围或嵌套范围内的所有日志语句都会从所有这些范围中获取信息)
ASP.NET 中默认创建的一些日志作用域是RequestId上面所示的作用域以及从日志中看到的围绕 MVC 控制器操作调用的作用域(例如这一行=> WebApplication8.Controllers.ValuesController.Get (WebApplication8):)
如果需要,您也可以自己创建范围:
using (logger.BeginScope("OrderOrchestrationId:{OrderOrchestrationId}", orderOrchestrationId))
{
// any log statements from here on would have `OrderOrchestrationId` available
}
Run Code Online (Sandbox Code Playgroud)
注意:
默认情况下,所有记录器都不支持范围。如果ConsoleLogger它以文本格式打印出范围,但在结构化日志记录的情况下,范围确实很出色,如下所述。
范围有何用处?
ASP.NET 日志记录框架允许您执行structured logging. 例如,上面的代码{OrderOrchestrationId}就是用于此目的的。Serilog有一个用于 ASP.NET 5 的记录器,它实现结构化日志记录,使用它您可以将数据作为json数据写入 Azure 的 DocumentDB。因此,在这种情况下,如果OrderOrchestrationId写入 Azure 的 DocumentDB,您可以使用此 id 搜索日志,这对于纯文本文件搜索来说是很难做到的。
| 归档时间: |
|
| 查看次数: |
1425 次 |
| 最近记录: |