日志概念
? ? ? ? 日志級別
? ? ? 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();}}
}