一、前言
1、本教程主要內(nèi)容
- ASP.NET Core + 內(nèi)置日志組件記錄控制臺日志
- ASP.NET Core + NLog 按天記錄本地日志
- ASP.NET Core + NLog 將日志按自定義LoggerName分類記錄到不同目錄
- ASP.NET Core + NLog 按文件大小歸檔記錄本地日志
- NLog配置文件常用配置項說明
2、本教程環(huán)境信息
| 軟件/環(huán)境 | 說明 |
|---|---|
| 操作系統(tǒng) | Windows 10 |
| SDK | 2.1.401 |
| ASP.NET Core | 2.1.3 |
| IDE | Visual Studio Code 1.33.0 |
| 瀏覽器 | Chrome 73 |
| VS Code插件 | 版本 | 說明 |
|---|---|---|
| C# | 1.18.0 | 提供C#智能感知, .NET Core 調(diào)試、編譯等 |
| vscdoe-solution-explorer | 0.3.1 | 提供解決方案視圖 |
| XML Tools | 2.4.0 | 提供XML高亮,格式化、XML樹等 |
本篇代碼以下代碼進行調(diào)整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
二、ASP.NET Core 內(nèi)置日志組件使用
ASP.NET Core內(nèi)置日志組件,可以將日志輸出在控制臺
1、應(yīng)用程序啟動時配置日志
修改Program.cs,在WebHostBuilder構(gòu)建時配置日志
//需要引入的命名空間
using Microsoft.Extensions.Logging;
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Info);
logging.AddConsole();
});
| 配置項 | 說明 |
|---|---|
| ClearProviders() | 清除日志提供程序,通常在引入第三方日志組件時使用 |
| SetMinimumLevel(LogLevel.Information) | 設(shè)置日志級別為Information |
| AddConsole() | 添加日志提供程序->控制臺 |
這里設(shè)置項,主要是SetMinimumLevel(LogLevel.Information),我們把日志級別設(shè)置為Information,可以減少很多控制臺日志輸出
2、在控制中記錄日志
修改HomeController.cs,通過構(gòu)造函數(shù)注入ILogger
//需要引入的命名空間
using Microsoft.Extensions.Logging;
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
this._logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation("------\r\nindex:hello world\r\n------");
return Content("Hello World ! -ken.io");
}
public IActionResult CheckPhone(string phone)
{
_logger.LogInformation($"------\r\ncheck phone:{phone}\r\n------");
var result = true;
var message = "pass";
if (string.IsNullOrWhiteSpace(phone))
{
result = false;
message = "phone number is empty";
_logger.LogError($"------\r\ncheck phone:{message}\r\n------");
}
else if (phone.Length != 11)
{
result = false;
message = "wrong phone number length";
_logger.LogWarning($"------\r\ncheck phone:{message}\r\n------");
}
return Json(new { Result = result, Phone = phone, Message = message });
}
這里日志內(nèi)容中包含的\r\n轉(zhuǎn)義符在控制臺輸出時/寫入文件時表示換行,這里加入\r\n和---主要是為了日志輸出時,方便快速找到我們主動記錄的日志。
3、驗證
啟動應(yīng)用,訪問 localhost:5001,會看到控制臺輸出了Hello World

訪問 localhost:5001/home/checkphone,將會看到Error日志

訪問 localhost:5001/home/checkphone?phone=000,將會看到警告日志

訪問 localhost:5001/home/checkphone?phone=16666666666,就只會看到Info級別日志了

三、ASP.NET Core + NLog 記錄本地日志
1、安裝NLog Package
在控制臺使用命令安裝NLog包:
//進入項目目錄
cd Ken.Tutorial.Web
//使用命令安裝nlog
dotnet add package NLog.Web.AspNetCore --version 4.8.1
這里我安裝的指定版本:4.8.1,如果不指定版本號,默認安裝最新版本。
2、引入NLog
修改Program.cs,在WebHostBuilder構(gòu)建時配置日志
//需要引入的命名空間
using NLog.Web;
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Info);
logging.AddConsole();
}).UseNLog();//UseNLog
3、配置NLog
在項目根目錄Ken.Tutorial.Web新建NLog配置文件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">
<targets>
<target name="defaultlog" xsi:type="File" keepFileOpen="false" encoding="utf-8"
fileName="${basedir}/logs/${level}/${shortdate}.log"
layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
</targets>
<rules>
<logger name="*" minlevel="trace" writeTo="defaultlog" />
</rules>
</nlog>
NLog配置文件一般主要包含兩個部分,<targets>節(jié)點配置日志寫入目標,<rules>節(jié)點配置匹配路由到<targets>的規(guī)則。
| 主要配置項 | ken.io的說明 |
|---|---|
|
|
表示在程序運行目錄,分日志級別按天寫入日志文件 |
|
|
日志內(nèi)容格式:時間+日志級別+LoggerName+日志內(nèi)容 |
| <logger name="*" minlevel="trace" writeTo="defaultlog" /> | 支持將任意級別、任意LoggerName的日志寫入target:defaultlog |
為了能讓程序運行時能夠讀取到配置文件,需要修改Ken.Tutorial.Web.csproj文件,在生成運行文件到bin文件夾時,也把nlog.config復(fù)制過去。在工具欄切換到資源管理器視圖,雙擊文件即可修改:

<ItemGroup>
<Content Update="nlog.config" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
4、NLog測試
啟動應(yīng)用,分別訪問以下鏈接:
- localhost:5001/home/checkphone
- localhost:5001/home/checkphone?phone=000
- localhost:5001/home/checkphone?phone=16666666666
然后在資源管理器視圖下,查看bin/Debug目錄,會看到日志已經(jīng)按照配置文件的格式生成了對應(yīng)的日志目錄及文件。

同時也會發(fā)現(xiàn),nlog.config按照之前的配置也被復(fù)制到了程序運行目錄。
- Info級別日志

- Warn級別日志

- Error級別日志

這里Info日志是比較多的,我們可以通過配置rules,只輸出程序本身主動記錄的日志。
<logger name="Ken.Tutorial.*" minlevel="trace" writeTo="defaultlog" />
四、NLog使用進階
1、通過自定義LoggerName歸納日志
增加NLog配置,根據(jù)LoggerName創(chuàng)建目錄
<!--按照LoggerName分類-->
<target name="customlog" xsi:type="File" keepFileOpen="false" encoding="utf-8"
fileName="${basedir}/logs/${logger}/${shortdate}-${level}.log"
layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
<!--記錄LoggerName以log結(jié)尾的日志-->
<logger name="*log" minlevel="trace" writeTo="customlog" />
在HomeController中添加測試歸納日志的Action
public IActionResult TestLog()
{
var logger = NLog.LogManager.GetLogger("testlog");
logger.Trace("這是Trace日志");
logger.Debug("這是Debug日志");
logger.Info("這是Info日志");
logger.Warn("這是警告日志");
logger.Error("這是錯誤日志");
return Content("ok");
}
這里直接通過NLog.LogManager.GetLogger創(chuàng)建Logger,并沒有使用內(nèi)置日志Microsoft.Extensions.Logging.ILogger的實例,所以可以自定義LoggerName,另外,我們在應(yīng)用啟動時配置的最低日志級別等也不會對這種方式生效,是可以輸出Trace、Debug級別的日志的。
啟動應(yīng)用,訪問:localhost:5001/home/testlog,然后就可以在資源管理器界面看到在logs文件夾下按照LoggerName生成的日志目錄,并按照日志級別生成了不同的日志文件:

2、按照日志文件大小歸檔日志
增加NLog配置,按照日志文件大小歸檔
<!--按照日志文件大小歸檔-->
<target name="archivelog" xsi:type="File" keepFileOpen="false" encoding="utf-8"
fileName="${basedir}/logs/${logger}/${shortdate}-current.log"
archiveFileName="${basedir}/logs/${logger}/${shortdate}.{####}.log"
archiveAboveSize="1024000"
archiveNumbering="Sequence"
maxArchiveFiles="100"
layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
這里配置當日志文件大小在超過約1mb的時候歸檔(這里偷懶用1000b代替1kb),最多歸檔100個日志文件,當歸檔日志文件超過100個時會把最早歸檔的日志刪除。
定義專屬規(guī)則:
<logger name="logmany" minlevel="trace" writeTo="archivelog" />
在HomeController中添加測試歸檔日志的Action
public IActionResult TestLogMany()
{
var logger = NLog.LogManager.GetLogger("logmany");
for (int i = 0; i <= 30000; i++)
{
logger.Info("ASP.NET Core入門教程,這里是日志內(nèi)容,測試NLog的日志歸檔功能,ken的雜談(https://ken.io)");
}
return Content("ok");
}
這里為了方便測試,直接用for循環(huán),連續(xù)寫入日志30000次
啟動應(yīng)用,訪問:localhost:5001/home/testlogmany,然后就可以在資源管理器界面看到在logs/logmany文件夾下按照文件大小歸檔的日志

五、備注
1、NLog常用配置項說明
| target節(jié)點/屬性 | ken.io的說明 |
|---|---|
| target | 日志寫入目標,可以配置寫入類型、寫入模板、文件名等 |
| name | TargetName,需要唯一,在rules節(jié)點引用 |
| xsi:type | 目標類型,支持文件(File)、數(shù)據(jù)庫(Database)、郵件(Mail) |
| keepFileOpen | 保持文件打開,不用每次寫入日志時都打開、關(guān)閉文件,因為可以提高性能,默認值為:false |
| encoding | 文件編碼,此處配置為:utf-8 |
| fileName | 日志文件名,包含日志完整路徑和文件名,支持模板語法/變量 |
| archiveFileName | 歸檔日志文件名,包含日志完整路徑和文件名,支持模板語法/變量 |
| archiveNumbering | 歸檔序號方式 |
| maxArchiveFiles | 最大歸檔日志文件數(shù) |
| layout | 日志內(nèi)容模板,內(nèi)置了一些語法/變量 |
| 模板語法/變量 | ken.io的說明 |
|---|---|
| ${basedir} | 程序當前運行目錄 |
| ${level} | 日志級別 |
| ${shortdate} | 當前日期,例如:2019-04-05 |
| ${longdate} | 當前時間,精確到毫秒,例如:2019-04-05 14:10:22.4372 |
|
|
把內(nèi)容格式化成大寫 |
| ${logger} | LoggerName,日志記錄器名稱,通常是Logger初始化所在類完整名稱,例如:Ken.Tutorial.Web.Controllers.HomeController |
| ${machinename} | 機器名 |
| ${message} | 日志內(nèi)容 |
| rules節(jié)點/屬性 | ken.io的說明 |
|---|---|
| logger | 日志記錄器路由規(guī)則配置 |
| name | LoggerName匹配,支持完整匹配和模糊匹配,例如:mylog、Ken.* |
| minlevel | 最低日志級別 |
| maxlevel | 最高日志級別 |
| level | 限制單一的日志級別 |
| levels | 指定一個或多個日志級別,用,間隔 |
| writeTo | 指定一個或多個target,用,間隔 |
| final | 在匹配到該規(guī)則之后不再匹配后續(xù)規(guī)則,默認值:false |
| enabled | 是否啟用該規(guī)則,默認值:true |
2、附錄
- 本文代碼示例
https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-10
- 本文參考
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1
https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2