ASP.NET Core 中文文档 第三章 原理(8)日志
- 作者: 五速梦信息网
- 时间: 2026年04月04日 13:50
ASP.NET Core 内建支持日志,也允许开发人员轻松切换为他们想用的其他日志框架。尽量用最少的代码来实现应用程序日志,只要做到这点,就能想在哪里加就能在那里加日志记录。
章节:
在应用程序中实现日志ILoggerFactoryILoggerILoggerFactoryCreateLogger
var logger = loggerFactory.CreateLogger("Catchall Endpoint");
logger.LogInformation("No endpoint found for request {path}", context.Request.Path);
.在应用程序中配置日志dotnet runlocalhost:5000
info[Catchall Endpoint]
{path}
logger.LogInformation("No endpoint found for request {path}", context.Request.Path);
在实际的应用程序中,你会希望基于应用程序级别来添加日志,而不是基于框架级别或事件。例如,你创建了一个 Web API 应用程序来管理 To-Do 条目(参见 用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API ),你可能会为这些条目的各种操作添加日志记录。
TodoControllerILoggerFactoryILoggerTodoControllerILoggerT
[Route("api/[controller]")]
public class TodoController : Controller
{
private readonly ITodoRepository _todoRepository;
private readonly ILogger<TodoController> _logger;
public TodoController(ITodoRepository todoRepository,
ILogger<TodoController> logger)
{
_todoRepository = todoRepository;
_logger = logger;
}
[HttpGet]
public IEnumerable<TodoItem> GetAll()
{
_logger.LogInformation(LoggingEvents.LIST_ITEMS, "Listing all items");
EnsureItems();
return _todoRepository.GetAll();
}
_logger
使用 ILogger
ILoggerTTodoControllerILoggerILoggerFactoryILoggerFactory
日志记录级别
当应用程序添加一条日志记录时,必须指定 日志级别 。日志级别允许你控制应用程序输出日志的详细程度,以及把不同类型的日志传送给不同的日志记录器。比方说,你可能会希望调试消息在一个本地文件,而把错误消息记录到计算机的事件日志或数据库中。
ASP.NET Core 详尽地定义了六个日志级别,通过增加重要性或严重程度排序:
Credentials: {"User":"someuser", "Password":"P@ssword"}
Entering method Configure with flag set to true
VerboseRequest received for path /foo
Login failed for IP 127.0.0.1FileNotFoundException for file foo.txt
Cannot insert record due to duplicate key violation
Critical
当应用程序或系统崩溃、遇到灾难性故障,需要立即被关注时,应当记录关键级别的日志。举例:数据丢失、磁盘空间不够等。
LoggingLogLevelLogInformationLog(LogLevel.Information, ...)LogLevel
string data
记录消息。
EventId eventId
使用数字类型的 id 来标记日志,这样可以将一系列的事件彼此相互关联。被记录的事件 ID 应该是静态的、特定于指定类型时间的。比如,你可能会把添加商品到购物车的事件 ID 标记为 1000,然后把结单的事件 ID 标记为 1001,以便能智能过滤并处理这些日志记录。
string format
日志消息的格式字符串。
object[] args
用于格式化的一组对象。
Exception error
用于记录的异常实例。
EventIdintint
ConsoleLoggereventId
TodoControllerInformationWarning
[HttpGet]
public IEnumerable<TodoItem> GetAll()
{
_logger.LogInformation(LoggingEvents.LIST_ITEMS, "Listing all items");
EnsureItems();
return _todoRepository.GetAll();
}
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(string id)
{
_logger.LogInformation(LoggingEvents.GET_ITEM, "Getting item {0}", id);
var item = _todoRepository.Find(id);
if (item == null)
{
_logger.LogWarning(LoggingEvents.GET_ITEM_NOTFOUND, "GetById({0}) NOT FOUND", id);
return NotFound();
}
return new ObjectResult(item);
}
注解
建议在应用程序及其 API 上执行应用程序日志记录,而不是在框架级别上记录。框架已经有了一个内建的能够简单通过设置启用相应日志级别的日志记录器了。
DebugTraceConfigureAddConsoleLogLevel.Trace

控制台记录器输出时使用前缀「dbug: 」,默认的框架没有追踪的记录器,每一个日志级别都有使用对应的四个字符的前缀,使得日志信息始终一致。
| Log Level | Prefix |
|---|---|
| Critical | crit |
| Error | fail |
| Warning | warn |
| Information | info |
| Debug | dbug |
| Trace | trce |
作用域
IDisposableILogger.BeginScopeTraceSource
作用域不是必须的,而且需要谨慎使用。它们适合用于具有比较明显的开始和结束的操作,比如在一个事务中调用多个资源。
在应用程序中配置日志StartupConfigureILoggerFactorydependency-injectionConfigureILoggerFactoryILoggerFactoryConfigureloggerFactory.AddConsoleMinimumLevelVerbose
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
ILoggerFactoryloggerFactory.AddConsole
注解
你可以选择配置日志记录,当设置 hosting 时,而不是在启动时。
ILoggerFactorylogLevel => logLevel >= LogLevel.Warning(category, loglevel) => category.Contains("MyController") && loglevel >= LogLevel.TraceEventLogSettingsFilterSourceSwitchTraceListener
FilterLoggerSettingsWithFilterILoggerFactoryILoggerFactoryILoggerFactory
loggerFactory
.WithFilter(new FilterLoggerSettings
{
{ "Microsoft", LogLevel.Warning },
{ "System", LogLevel.Warning },
{ "ToDoApi", LogLevel.Debug }
})
.AddConsole();
配置 TraceSource 日志
TraceSource
Microsoft.Extensions.Logging.TraceSourceTextWriterTraceListener
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Filter": "1.0.0",
"Microsoft.Extensions.Logging.TraceSource": "1.0.0"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": {
TraceSourceLoggerWarningAddTraceSourceTraceListenerTextWriterTraceListener
// add Trace Source logging
var testSwitch = new SourceSwitch("sourceSwitch", "Logging Sample");
testSwitch.Level = SourceLevels.Warning;
loggerFactory.AddTraceSource(testSwitch,
new TextWriterTraceListener(writer: Console.Out));
sourceSwitchSourceLevels.WarningWarningTraceListener
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using TodoApi.Core;
using TodoApi.Core.Interfaces;
using TodoApi.Core.Model;
namespace TodoApi.Controllers
{
[Route("api/[controller]")]
public class TodoController : Controller
{
private readonly ITodoRepository _todoRepository;
private readonly ILogger<TodoController> _logger;
public TodoController(ITodoRepository todoRepository,
ILogger<TodoController> logger)
{
_todoRepository = todoRepository;
_logger = logger;
}
[HttpGet]
public IEnumerable<TodoItem> GetAll()
{
_logger.LogInformation(LoggingEvents.LIST_ITEMS, "Listing all items");
EnsureItems();
return _todoRepository.GetAll();
}
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(string id)
{
_logger.LogInformation(LoggingEvents.GET_ITEM, "Getting item {0}", id);
var item = _todoRepository.Find(id);
if (item == null)
{
_logger.LogWarning(LoggingEvents.GET_ITEM_NOTFOUND, "GetById({0}) NOT FOUND", id);
return NotFound();
}
return new ObjectResult(item);
}
[HttpPost]
public IActionResult Create([FromBody] TodoItem item)
{
if (item == null)
{
return BadRequest();
}
_todoRepository.Add(item);
_logger.LogInformation(LoggingEvents.INSERT_ITEM, "Item {0} Created", item.Key);
return CreatedAtRoute("GetTodo", new { controller = "Todo", id = item.Key }, item);
}
[HttpPut("{id}")]
public IActionResult Update(string id, [FromBody] TodoItem item)
{
if (item == null || item.Key != id)
{
return BadRequest();
}
var todo = _todoRepository.Find(id);
if (todo == null)
{
_logger.LogWarning(LoggingEvents.GET_ITEM_NOTFOUND, "Update({0}) NOT FOUND", id);
return NotFound();
}
_todoRepository.Update(item);
_logger.LogInformation(LoggingEvents.UPDATE_ITEM, "Item {0} Updated", item.Key);
return new NoContentResult();
}
[HttpDelete("{id}")]
public void Delete(string id)
{
_todoRepository.Remove(id);
_logger.LogInformation(LoggingEvents.DELETE_ITEM, "Item {0} Deleted", id);
}
private void EnsureItems()
{
if (!_todoRepository.GetAll().Any())
{
_logger.LogInformation(LoggingEvents.GENERATE_ITEMS, "Generating sample items.");
for (int i = 1; i < 11; i++)
{
_todoRepository.Add(new TodoItem() { Name = "Item " + i });
}
}
}
}
}
http://localhost:5000/api/Todo/0
ConsoleLoggerTextWriterTraceListenerTextWriter
配置其它提供程序
ILoggerFactory
你也可以创建自己定制的提供程序来支持其他的日志框架或自己内部的日志需求。
日志记录建议当你在 ASP.NET Core 应用程序中实现日志时可以参考以下有用建议:
LogLevelCreate
总结
Startup
- 上一篇: ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览
- 下一篇: ASP.Net Core 中使用Zookeeper搭建分布式环境中的配置中心系列一:使用Zookeeper.Net组件演示基本的操作
相关文章
-
ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览
ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览
- 互联网
- 2026年04月04日
-
ASP.NET Core 中文文档 第四章 MVC(3.9)视图组件
ASP.NET Core 中文文档 第四章 MVC(3.9)视图组件
- 互联网
- 2026年04月04日
-
ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器
ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器
- 互联网
- 2026年04月04日
-
ASP.Net Core 中使用Zookeeper搭建分布式环境中的配置中心系列一:使用Zookeeper.Net组件演示基本的操作
ASP.Net Core 中使用Zookeeper搭建分布式环境中的配置中心系列一:使用Zookeeper.Net组件演示基本的操作
- 互联网
- 2026年04月04日
-
ASP.NET Core 之 Identity 入门(一)
ASP.NET Core 之 Identity 入门(一)
- 互联网
- 2026年04月04日
-
ASP.NET Core 微信支付(三)【查询订单 APIV3】
ASP.NET Core 微信支付(三)【查询订单 APIV3】
- 互联网
- 2026年04月04日





