日志概念
日志级别
NET (Microsoft.Extensions.Logging
) 中定义的 6 个标准日志级别,按严重性从低到高排列:
日志级别 | 数值 | 描述 | 典型使用场景 |
---|---|---|---|
Trace | 0 | 最详细的信息,包含敏感数据(如请求体、密码哈希等)。仅在开发或深度故障排除时启用。 | 记录方法入口/出口、详细变量值、低级别通信细节。 |
Debug | 1 | 开发调试信息。比 Trace 略少细节,但仍包含对开发者有用的内部信息。 | 记录关键变量状态、流程步骤、非性能关键操作的耗时、配置加载值。 |
Information | 2 | 应用程序流信息。描述应用程序正常、预期内的操作。 | 服务启动/停止、重要操作完成(如“用户登录成功”、“订单创建”)、主要里程碑事件。 |
Warning | 3 | 异常或意外事件,但应用程序仍能继续运行。表明可能需要调查的潜在问题。 | 重试操作、降级功能使用、预期内的外部服务错误、接近资源限制(如磁盘空间不足)。 |
Error | 4 | 无法处理的错误。表示当前操作或请求失败,但应用程序整体仍可运行。 | 捕获的异常、数据库连接失败、关键操作失败(如支付处理失败)、外部API调用关键错误。 |
Critical | 5 | 最严重的故障,可能导致应用程序崩溃或不可恢复的损坏。需要立即处理。 | 系统崩溃、数据丢失、磁盘空间耗尽、启动失败、灾难性未处理异常。 |
日志提供者:需要把日志输出那个地方文件,数据库,控制台等。
输出日志到控制台
1.安装Nuget日志所需要的包:
Microsoft.Extensions.Logging.Console
2.DI注入:
//创建DI容器对象
ServiceCollection services = new ServiceCollection();
services.AddLogging(logBuilder => {
//容器注入控制台输出
logBuilder.AddConsole();
详细步骤:
1.创建一个类,使用构造方法注入ILogger<一般填写当前类名>
class TestLog
{//定义一个ILogger类型私有变量,泛型中类型填写本类private readonly ILogger<TestLog> logger;//使用构造方法进行注入public TestLog(ILogger<TestLog> logger) { this.logger = logger;}public void Log(){logger.LogDebug("调试记录信息");logger.LogWarning("警告记录信息");logger.LogError("错误记录信息");}}
2.在主程序中创建DI容器,注册服务、添加控制器输出
public class Program{static void Main(string[] args){//创建DI容器对象ServiceCollection services = new ServiceCollection();services.AddLogging(logBuilder => {//-----------------------------------//容器注入控制台输出logBuilder.AddConsole();//--------------------------------------//设置输出级别为最低logBuilder.SetMinimumLevel(LogLevel.Trace); });//容器注册服务对象services.AddScoped<TestLog>();//构建一个服务提供者(Service Provider)对象//创建一个 `ServiceProvider` 实例。//-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务using (var sp = services.BuildServiceProvider()){//获取服务对象TestLog tlog = sp.GetRequiredService<TestLog>();tlog.Log();Console.ReadKey();}}}
3.输出结果
输出日志到Windows的事件查看器中
1.创建一个类,使用构造方法注入ILogger<一般填写当前类名>
class TestLog
{//定义一个ILogger类型私有变量,泛型中类型填写本类private readonly ILogger<TestLog> logger;//使用构造方法进行注入public TestLog(ILogger<TestLog> logger) { this.logger = logger;}public void Log(){logger.LogDebug("调试记录信息");logger.LogWarning("警告记录信息");logger.LogError("错误记录信息");}}
2.在主程序中创建DI容器,注册服务、添加事件查看器输出
public class Program{static void Main(string[] args){//创建DI容器对象ServiceCollection services = new ServiceCollection();services.AddLogging(logBuilder => {//---------------------------------------//注入windows事件查看器中输出logBuilder.AddEventLog();//---------------------------------------//设置输出级别为最低logBuilder.SetMinimumLevel(LogLevel.Trace); });//容器注册服务对象services.AddScoped<TestLog>();//构建一个服务提供者(Service Provider)对象//创建一个 `ServiceProvider` 实例。//-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务using (var sp = services.BuildServiceProvider()){//获取服务对象TestLog tlog = sp.GetRequiredService<TestLog>();tlog.Log();Console.ReadKey();}}}
3.输出结果
NLog文本日志输出
1.安装Nuget包:NLog.Extensions.Logging
控制台输入:Install-Package NLog.Extensions.Logging
2..创建配置文件
添加 nlog.config
配置文件(右键项目 → 新建项 → NLog 配置文件),nlog.config
位于项目根目录
内容示例如下:
<?xml version="1.0" encoding="utf-8"?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"autoReload="true"internalLogLevel="info"internalLogFile="interal_NLog.log"throwExceptions="false" encoding="utf-8"><targets><!-- 控制台输出 ,layout输出布局格式--><target name="console" xsi:type="Console" layout="${longdate}|${level}|${message}" /><!-- 文件输出(按日期分目录) --><target name="file" xsi:type="File" fileName="Logs/${date:format=yyyy}/${date:format=MM}/${shortdate}.log"layout="${longdate}|${level}|${logger}|${message} ${exception}" /></targets><rules><!--输出日志的匹配规则 ,以name名称进行匹配,输入日志的等级,输出到哪里--><logger name="*" minlevel="Info" writeTo="console,file" /><logger name="*" minlevel="Debug" writeTo="file" /></rules>
</nlog>
关键设置:将文件属性设为 复制到输出目录:【始终复制】
3.创建一个类,使用构造方法注入ILogger<一般填写当前类名>
class TestLog
{//定义一个ILogger类型私有变量,泛型中类型填写本类private readonly ILogger<TestLog> logger;//使用构造方法进行注入public TestLog(ILogger<TestLog> logger) { this.logger = logger;}public void Log(){logger.LogDebug("调试记录信息");logger.LogWarning("警告记录信息");logger.LogError("错误记录信息");}}
4.在主程序中创建DI容器,注册服务、添加Nlog文本输出
public class Program{static void Main(string[] args){//创建DI容器对象ServiceCollection services = new ServiceCollection();services.AddLogging(logBuilder => {//========================NLog日志========================//注入NLog日志logBuilder.AddNLog();//========================================================//设置输出级别为最低logBuilder.SetMinimumLevel(LogLevel.Trace); });//容器注册服务对象services.AddScoped<TestLog>();//构建一个服务提供者(Service Provider)对象//创建一个 `ServiceProvider` 实例。//-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务using (var sp = services.BuildServiceProvider()){//获取服务对象TestLog tlog = sp.GetRequiredService<TestLog>();tlog.Log();Console.ReadKey();}}}
配置高级设置
-
异步日志提升性能
<!-- AsyncWrapper 时会自动启用批量写入--> <target name="asyncFile" xsi:type="AsyncWrapper"><target xsi:type="File" fileName="logs/async.log" KeepFileOpen=false async="true"/> </target>
-
避免阻塞主线程,适合高并发场景。
-
-
全局诊断上下文(GDC)
-
设置全局变量(如应用版本):
NLog.GlobalDiagnosticsContext.Set("AppVersion", "2.0.0");
-
配置中引用:
${gdc:item=AppVersion}
-
-
日志轮转与压缩
<target xsi:type="File" fileName="logs/app.log"maxArchiveFiles="30" <!-- 保留30个文件 -->archiveAboveSize="10485760" <!-- 单个文件 >10MB 时分割 -->enableArchiveFileCompression="true" /> <!--启用文档压缩 -->
⚡ 五、性能优化建议
-
缓冲写入:减少 I/O 操作
<target xsi:type="BufferingWrapper" bufferSize="1000"><target xsi:type="File" fileName="logs/buffered.log" /> </target>
-
按环境调整日志级别:
-
开发环境:
Debug
-
生产环境:
Warn
或Error
。
-
-
条件日志记录:避免不必要的计算
if (logger.IsEnabled(LogLevel.Debug)) {var data = ExpensiveOperation();logger.Debug(data); }
目标标签配置选项:
-
File target · NLog/NLog 数据库
https://github.com/NLog/NLog/wiki/Database-target
-
File target · NLog/NLog Wiki · GitHub
https://github.com/NLog/NLog/wiki/File-target
-
NLog 和 SQL Server 示例配置
<target name="database" xsi:type="Database"><connectionString>server=localhost;Database=*****;user id=****;password=*****</connectionString><!--数据库中创建日志表Script for creating the dbo.Log table.SET ANSI_NULLS ONSET QUOTED_IDENTIFIER ONCREATE TABLE [dbo].[Log] ([Id] [int] IDENTITY(1,1) NOT NULL,[MachineName] [nvarchar](50) NOT NULL,[Logged] [datetime] NOT NULL,[Level] [nvarchar](50) NOT NULL,[Message] [nvarchar](max) NOT NULL,[Logger] [nvarchar](250) NULL,[Exception] [nvarchar](max) NULL,CONSTRAINT [PK_dbo.Log] PRIMARY KEY CLUSTERED ([Id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]--><commandText>insert into dbo.Log (MachineName, Logged, Level, Message,Logger, Exception) values (@MachineName, @Logged, @Level, @Message,@Logger, @Exception);</commandText><parameter name="@MachineName" layout="${machinename}" /><parameter name="@Logged" layout="${date}" /><parameter name="@Level" layout="${level}" /><parameter name="@Message" layout="${message}" /><parameter name="@Logger" layout="${logger}" /><parameter name="@Exception" layout="${exception:tostring}" /> </target>
Serilog结构化日志输出
- 官方文档:NuGet 库 |Serilog.AspNetCore 9.0.0
https://www.nuget.org/packages/Serilog.AspNetCore/9.0.0
- 安装Nuget包:
- Serilog.AspNetCore
日志设置:
Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().MinimumLevel.Override("Microsoft", LogEventLevel.Information).Enrich.FromLogContext().WriteTo.Console()// Add this line:.WriteTo.File(//连接路径 存放位置:C:\Users\xxxxxx\LogFiles\Application\diagnostics.txtSystem.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), "LogFiles", "Application", "diagnostics.txt"),rollingInterval: RollingInterval.Day,fileSizeLimitBytes: 10 * 1024 * 1024,retainedFileCountLimit: 2,rollOnFileSizeLimit: true,shared: true,flushToDiskInterval: TimeSpan.FromSeconds(1)).CreateLogger();//添加serilog日志对象services.AddSerilog();
完整代码:
1.安装serilog包:
Install-Package Serilog.AspNetCore
2.创建一个类,使用构造方法注入ILogger<一般填写当前类名>
class TestLog
{//定义一个ILogger类型私有变量,泛型中类型填写本类private readonly ILogger<TestLog> logger;//使用构造方法进行注入public TestLog(ILogger<TestLog> logger) { this.logger = logger;}public void Log(){logger.LogDebug("调试记录信息");logger.LogWarning("警告记录信息");logger.LogError("错误记录信息");}}
3.在主程序中创建DI容器,注册服务、添加serilog文本输出
public class Program
{static void Main(string[] args){//创建DI容器对象ServiceCollection services = new ServiceCollection();services.AddLogging(logBuilder => {//存放日志路径string path = System.IO.Path.Combine(Environment.GetEnvironmentVariable("HOME"), "LogFiles", "Application", "diagnostics.txt");//serilog日志的设置Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().Enrich.FromLogContext().WriteTo.Console(new JsonFormatter()).WriteTo.File(path,rollingInterval: RollingInterval.Day,fileSizeLimitBytes: 10 * 1024 * 1024,retainedFileCountLimit: 2,rollOnFileSizeLimit: true,shared: true,flushToDiskInterval: TimeSpan.FromSeconds(1)).CreateLogger();//添加serilog日志对象logBuilder.AddSerilog();//设置输出级别为最低logBuilder.SetMinimumLevel(LogLevel.Trace); });//容器注册服务对象services.AddScoped<TestLog>();//构建一个服务提供者(Service Provider)对象//创建一个 `ServiceProvider` 实例。//-这个 `ServiceProvider` 对象就是依赖注入容器,它负责管理服务的生命周期和解析服务using (var sp = services.BuildServiceProvider()){//获取服务对象TestLog tlog = sp.GetRequiredService<TestLog>();tlog.Log();Console.ReadKey();}}
}