主要参考:ASP.NET Core 中的日志记录
首先创建了一个MVC项目
dotnet new mvc -n mvcSite
然后考虑添加日志组件的引用
Install-Package Microsoft.Extensions.Logging
asp.net 内置日志记录提供程序包括:Console、Debug、EventSource 等
- 控制台提供程序Microsoft.Extensions.Logging.Console 提供程序包向控制台发送日志输出。
- 调试提供程序Microsoft.Extensions.Logging.Debug 提供程序包使用 System.Diagnostics.Debug 类(Debug.WriteLine 方法调用)来写入日志输出。
在 Linux 中,此提供程序将日志写入 /var/log/message 。 - EventSource 提供程序Microsoft.Extensions.Logging.EventSource 提供程序包可实现事件跟踪。 在 Windows 中,它使用 ETW。 提供程序可跨平台使用,但尚无支持 Linux 或 macOS 的事件集合和显示工具。
对比了一下,比较跨平台,又简单易用的也只有Console 控制台了
添加引用
Install-Package Microsoft.Extensions.Logging.Console
在代码中启用, 文件 Program.cs 中增加日志提供程序
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
});
创建一个演示控制器LoggingController
public class LoggingController: Controller
{
public IActionResult Index()
{
return Content("Hello Logging");
}
}
采用脚本http localhost:50010/Logging
测试接口,正常返回信息。服务端生成大量日志,日志级别:Info
ASP.NET Core 定义了以下日志级别(按严重性从低到高排列)。
Trace 跟踪 = 0
有关通常仅用于调试的信息。 这些消息可能包含敏感应用程序数据,因此不得在生产环境中启用它们。 默认情况下禁用。
Debug 调试 = 1
有关在开发和调试中可能有用的信息。 示例:Entering method Configure with flag set to true. 由于日志数量过多,因此仅当执行故障排除时,才在生产中启用 Debug 级别日志。
Information 信息 = 2
用于跟踪应用的常规流。 这些日志通常有长期价值。 示例:Request received for path /api/todo
Warning 警告 = 3
表示应用流中的异常或意外事件。 可能包括不会中断应用运行但仍需调查的错误或其他条件。 Warning 日志级别常用于已处理的异常。 示例:FileNotFoundException for file quotes.txt.
Error 错误 = 4
表示无法处理的错误和异常。 这些消息指示的是当前活动或操作(例如当前 HTTP 请求)中的失败,而不是整个应用中的失败。 日志消息示例:Cannot insert record due to duplicate key violation.
Critical 严重 = 5
需要立即关注的失败。 例如数据丢失、磁盘空间不足。
appsettings.Development.json
中配置了当前开发模式下的日志输出级别
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
"Microsoft" 设置为 Warning 警告,再次运行上面的脚本请求接口,服务端再不返回任何 Information 级别的日志。如果将日志级别降为 Debug 调试,输出更多日志,包括 Debug 级别和Information 级别。
为了演示出自定义的日志输出,防止底层日志干扰,暂时将"Microsoft" 设置为 Warning 警告。
public class LoggingController: Controller
{
ILogger _logger;
public LoggingController(ILogger logger)
{
_logger = logger;
}
public IActionResult Index()
{
var username = "zhangsan";
_logger.LogTrace("当前用户ID为",username);
_logger.LogDebug("当前为调试模式");
_logger.LogInformation("正在调用日志记录接口");
_logger.LogWarning("文件A未找到");
_logger.LogError("访问数据库异常");
_logger.LogCritical("内存已满,无法响应");
return Content("Hello Logging");
}
}
默认设置的日志级别为
Debug
,高于该级别的日志全部输出,只有跟踪级别的日志未能输出。
接下来继续到发布环境下查看下日志输出情况
编写Dockerfile -> 生成镜像->推送镜像库->编排容器->运行
编排脚本
version: '3.3'
services:
mvcSite:
image: registry.cn-beijing.aliyuncs.com/djm/mvcSite:latest
ports:
- "8081:80"
volumes:
- ./mvcSite/appsettings.json:/app/appsettings.json
networks:
- backend
restart: always
container_name: mvcSite_frame2019_test
networks:
backend:
再次采用脚本http localhost:8081/logging
测试,由于发布环境默认采用的日志级别是警告 Warning,控制台只返回来三条日志
mvcSite_frame2019_test | warn: mvcSite.Controllers.LoggingController[0]
mvcSite_frame2019_test | 文件A未找到
mvcSite_frame2019_test | fail: mvcSite.Controllers.LoggingController[0]
mvcSite_frame2019_test | 访问数据库异常
mvcSite_frame2019_test | crit: mvcSite.Controllers.LoggingController[0]
webftp_frame2019_test | 内存已满,无法响应
将容器日志保存为文件
在生产环境下,将日志输出到控制台可不行,上一节介绍过 fluentd 相关的文章 使用Fluentd收集Docker容器日志
改写编排脚本
version: '3.3'
services:
mvcSite:
image: registry.cn-beijing.aliyuncs.com/djm/mvcSite:latest
ports:
- "8081:80"
volumes:
- ./mvcSite/appsettings.json:/app/appsettings.json
networks:
- backend
restart: always
container_name: mvcSite_frame2019_test
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: mvcSite_frame2019_test
networks:
backend:
调用成功后,打开日志文件mvcSite_frame2019_test.20190614.log:
�[40m�[1m�[33mwarn�[39m�[22m�[49m: mvcSite.Controllers.LoggingController[0]
文件A未找到
�[41m�[30mfail�[39m�[22m�[49m: mvcSite.Controllers.LoggingController[0]
访问数据库异常
�[41m�[1m�[37mcrit�[39m�[22m�[49m: mvcSite.Controllers.LoggingController[0]
内存已满,无法响应
有一些控制字符成乱码了,不过还好,主要信息还能识别
后来换Serilog,对日志输出指定下字符串模板就没问题了
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")