.netcore3.1使用log4net/nlog記錄日志
使用log4net
第一步、在對應項目中引入log4net.Extensions.Logging
log4net.Extensions.Logging依賴於log4net,所以在引入時自動引入了log4net
第二步、創建log4net.config文件
詳細的配置說明請參照文檔:https://dotnetgreen.com/log4net-configuration/;http://logging.apache.org/log4net/release/manual/configuration.html,
創建log4net.config,配置好日志參數。並將改文件設置成【始終復制】或者【如果較新則復制】
log4net.config文件內容示例
<?xml version="1.0" encoding="utf-8"?> <log4net> <!-- Define some output appenders --> <appender name="rollingAppender" type="log4net.Appender.RollingFileAppender"> <file value="log\log.txt" /> <!--追加日志內容--> <appendToFile value="true" /> <!--防止多線程時不能寫Log,官方說線程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--可以為:Once|Size|Date|Composite--> <!--Composite為Size和Date的組合--> <rollingStyle value="Composite" /> <!--當備份文件時,為文件名加的后綴--> <datePattern value="yyyyMMdd.txt" /> <!--日志最大個數,都是最新的--> <!--rollingStyle節點為Size時,只能有value個日志--> <!--rollingStyle節點為Composite時,每天有value個日志--> <maxSizeRollBackups value="20" /> <!--可用的單位:KB|MB|GB--> <maximumFileSize value="5MB" /> <!--置為true,當前最新日志文件名永遠為file節中的名字--> <staticLogFileName value="true" /> <!--輸出級別在INFO和ERROR之間的日志--> <!--過濾級別 FATAL > ERROR > WARN > INFO > DEBUG--> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="WARN" /> <param name="LevelMax" value="FATAL" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> </layout> </appender> <root> <priority value="ALL"/> <level value="ALL"/> <appender-ref ref="rollingAppender" /> </root> </log4net>
第三步、代碼注入log4net,記錄日志
在startup.cs中注入log4net替換原有的日志組件
1 services.AddLogging(logBuilder=> { 2 logBuilder.ClearProviders(); 3 logBuilder.AddLog4Net(); 4 });
記錄日志
1 [Route("api/[controller]")] 2 [ApiController] 3 public class TestLoggerController : ControllerBase 4 { 5 private readonly ILogger<TestLoggerController> _logger; 6 public TestLoggerController(ILogger<TestLoggerController> logger) 7 { 8 this._logger = logger; 9 } 10 11 [HttpPost("testWriteLogException")] 12 public void TestWriteLogException() 13 { 14 _logger.LogError("這是一個簡單日志測試"); 15 16 } 17 }
結果
------------------------------------
使用NLog
第一步,項目中引入NLog.Extensions.Logging
第二步、創建nlog.config文件
詳細的配置說明請參照NLog官方文檔https://github.com/nlog/nlog/wiki/Configuration-file
。
創建nlog.config文件,設置好日志記錄規則信息,並將改文件設置成【始終復制】或者【如果較新則復制】
nlog.config文件示例
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Off" internalLogFile="d:\temp\internal-nlog.txt"> <!-- enable asp.net core layout renderers --> <extensions> <add assembly="NLog.Web.AspNetCore"/> </extensions> <!-- the targets to write to --> <targets> <!-- write logs to file --> <target xsi:type="File" name="allfile" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} ${level:uppercase=true} ${event-context:item=Action} ${message} ${event-context:item=Amount} ${stacktrace} ${newline} ${exception:format=tostring} ${newline}" /> <!-- another file log, only own logs. Uses some ASP.NET core renderers --> <target xsi:type="Debugger" name="debugger" layout="${date:format=HH\:mm\:ss.fff}: ${message}" /> </targets> <!-- rules to map from logger name to target --> <rules> <!--Skip non-critical Microsoft logs and so log only own logs--> <!--<logger name="Microsoft.*" maxlevel="Error" final="true" />--> <logger name="*" minlevel="Debug" writeTo="allfile" /> <!--<logger name="*" minlevel="Info" writeTo="allfile" />--> </rules> </nlog>
第三步、代碼中注入NLog
在startup.cs中注入NLog替換原來的日志組件
1 services.AddLogging(logBuilder=> { 2 logBuilder.ClearProviders(); 3 logBuilder.AddNLog(); 4 });
記錄日志
[Route("api/[controller]")] [ApiController] public class TestLoggerController : ControllerBase { private readonly ILogger<TestLoggerController> _logger; public TestLoggerController(ILogger<TestLoggerController> logger) { this._logger = logger; } [HttpPost("testWriteLogException")] public void TestWriteLogException() { _logger.LogError("這是一個簡單日志測試-----NLog"); } }
結果
-----------------------------------------
附,配置全局異常過濾
程序在運行中避免會出現各種異常,而我們不可能在所有地方都進行try..catch捕獲異常記錄日志。這時我們可以定義全局異常捕獲並記錄日志。
在netcore中我們只需要定義對應的異常過濾類(其必須繼承自ExceptionFilterAttribute或者是實現接口IExceptionFilter;ExceptionFilterAttribute實現了接口IExceptionFilter),並在程序中進行注入異常過濾即可(日志的記錄還是要依賴具體的實現,可以是log4net、NLog或者其他)。
以下定義了GlobalExceptionFilter
public class GlobalExceptionFilter : ExceptionFilterAttribute { private readonly ILogger<GlobalExceptionFilter> _logger; public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger) { _logger = logger; } public override void OnException(ExceptionContext context) { var operation = context.HttpContext.Request.RouteValues["controller"] + "/" + context.HttpContext.Request.RouteValues["action"]; _logger.LogError(context.Exception,$"{operation} Exception:" + context.Exception.Message); //記錄錯誤日志 //攔截處理 if (!context.ExceptionHandled) { context.Result = new JsonResult(new { status = false, msg ="系統內部錯誤:"+ context.Exception.Message }); context.ExceptionHandled = true; } } }
修改startup.cs添加異常過濾
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddMvc(p => { p.Filters.Add(typeof(GlobalExceptionFilter)); //添加異常過濾 }); .... }
示例
[Route("api/[controller]")] [ApiController] public class TestLoggerController : ControllerBase { private readonly ILogger<TestLoggerController> _logger; public TestLoggerController(ILogger<TestLoggerController> logger) { this._logger = logger; } [HttpPost("testWriteLogException")] public void TestWriteLogException() { throw new Exception("這是沒有捕獲的異常"); } }
結果
-----------------------------------------