Asp.Net Core用NLog記錄日志操作方法
需求
1.日志自動寫入到數(shù)據(jù)庫、寫入到文件
2.appsettings.json數(shù)據(jù)庫連接更改后,不需要去改NLog中的連接地址,啟動網站或項目時自動檢測變動然后去更改,以appsettings.json為準,保持同步。
3.寫入日志時,除了NLog自帶的字段,新增LogType自定義字段記錄日志類型,例如網站日志、中間件日志等
4.統(tǒng)一的寫日志方法,不用每次get一個logger對象(或依賴注入)來記日志
安裝包
在nuget中安裝NLog和NLog.Web.AspNetCore ,這兩個是NLog相關的包。
還需要安裝NLog寫入數(shù)據(jù)庫的數(shù)據(jù)庫適配器,我這里寫入到MySQL數(shù)據(jù)庫,所以安裝MySql.Data
如果是寫入到SQL server數(shù)據(jù)庫,需要安裝Microsoft.Data.SqlClient

NLog.config 配置文件內容
網站根目錄下新建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"
throwExceptions="false"
internalLogLevel="Off"
internalLogFile="NlogRecords.log">
<!--Nlog內部日志記錄為Off關閉。除非糾錯,不可以設為Trace否則速度很慢,起碼Debug以上-->
<extensions>
<add assembly="NLog.Web.AspNetCore" />
</extensions>
<targets>
<!--通過數(shù)據(jù)庫記錄日志 配置
dbProvider請選擇mysql或是sqlserver,同時注意連接字符串,需要安裝對應的sql數(shù)據(jù)提供程序
MYSQL:
dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"
connectionString="server=localhost;database=BaseMIS;user=root;password=123456"
MSSQL:
dbProvider="Microsoft.Data.SqlClient"
connectionString="Server=127.0.0.1;Database=BaseMIS;User ID=sa;Password=123456"
-->
<target name="log_database" xsi:type="Database" dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"
connectionString="server=192.168.137.10;database=TestNLog;user=root;password=mysql@local">
<commandText>
INSERT INTO TblLogrecords
(LogDate,LogLevel,LogType,Logger,Message,MachineName,MachineIp,NetRequestMethod
,NetRequestUrl,NetUserIsauthenticated,NetUserAuthtype,NetUserIdentity,Exception)
VALUES
(@LogDate,@LogLevel,@LogType,@Logger,@Message,@MachineName,@MachineIp,@NetRequestMethod
,@NetRequestUrl,@NetUserIsauthenticated,@NetUserAuthtype,@NetUserIdentity,@Exception);
</commandText>
<parameter name="@LogDate" layout="${date}" />
<parameter name="@LogLevel" layout="${level}" />
<parameter name="@LogType" layout="${event-properties:item=LogType}" />
<parameter name="@Logger" layout="${logger}" />
<parameter name="@Message" layout="${message}" />
<parameter name="@MachineName" layout="${machinename}" />
<parameter name="@MachineIp" layout="${aspnet-request-ip}" />
<parameter name="@NetRequestMethod" layout="${aspnet-request-method}" />
<parameter name="@NetRequestUrl" layout="${aspnet-request-url}" />
<parameter name="@NetUserIsauthenticated" layout="${aspnet-user-isauthenticated}" />
<parameter name="@NetUserAuthtype" layout="${aspnet-user-authtype}" />
<parameter name="@NetUserIdentity" layout="${aspnet-user-identity}" />
<parameter name="@Exception" layout="${exception:tostring}" />
</target>
<target name="log_file" xsi:type="File" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} | ${level:uppercase=false} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
</targets>
<rules>
<!--跳過所有級別的Microsoft組件的日志記錄-->
<logger name="Microsoft.*" final="true" />
<!-- BlackHole without writeTo -->
<!--只通過數(shù)據(jù)庫記錄日志,如果給了name名字,cs里用日志記錄的時候,取logger需要把name當做參數(shù)-->
<logger name="logdb" writeTo="log_database" />
<logger name="logfile" writeTo="log_file" />
</rules>
</nlog>
配置文件解讀 nlog根節(jié)點: autoReload屬性,true時,如果NLog.config文件有變動,會自動應用新配置(但是會有延遲,過幾秒才會應用起來) internalLogLevel屬性,設定后,輸出的是NLog內部自己的日志記錄,如果遇到NLog異常/配置文件沒配好,可以把Off改為Trace或Debug來查看NlogRecords.log里的內容 internalLogFile屬性,可以設定路徑,例如默認的c:\temp\nlog-internal.log 新增了extensions節(jié)點,因為引用了NLog.Web.AspNetCore包 targets節(jié)點中是各種記錄方式的配置第一個target節(jié)點,可以看到name是log_database,這里的name和下方logger中writeTo屬性對應 xsi:type="Database",就是寫入數(shù)據(jù)庫了 dbProvider屬性是數(shù)據(jù)庫適配器,MySQL是MySql.Data.MySqlClient.MySqlConnection, MySql.Data,SQL server是Microsoft.Data.SqlClient,其他數(shù)據(jù)庫適配器可在官方文檔內查看 connectionString即連接字符串了 commandText子節(jié)點是插入數(shù)據(jù)庫時insert語句,可以看到我這里是寫入到TblLogrecords表,表結構下文會展示出來 parameter子節(jié)點是insert語句的各個參數(shù): 有個name="@LogType"參數(shù),layout="${event-properties:item=LogType}",表示@LogType參數(shù)的值從event-properties中的LogType中取,這個后文會寫到用法其余參數(shù)均是NLog自帶的內容,aspnet-開頭的是NLog.Web.AspNetCore包中提供的方法 layout render官方文檔 第二個target節(jié)點,可以看到name是log_file,這里的name和下方logger中writeTo屬性對應 xsi:type="File",即寫入到文件 fileName屬性是文件名,這里是寫入到當前目錄下的logs文件夾,并且按日期歸檔 layout屬性是寫入日志的格式 rules節(jié)點是各個日志記錄器logger的配置 第一個logger配置跳過所有Microsoft組件的日志記錄,final 標記當前規(guī)則為最后一個規(guī)則。其后的規(guī)則即時匹配也不會被運行。第二個logger name="logdb",該日志記錄器名為logdb,是適配log_database規(guī)則,即寫入數(shù)據(jù)庫,如果要適配多條規(guī)則,用逗號隔開其余規(guī)則可以參考http://www.dhdzp.com/article/173004.htm 數(shù)據(jù)庫配置數(shù)據(jù)表結構
這里數(shù)據(jù)庫為TestNLog:
CREATE DATABASE IF NOT EXISTS `TestNLog`; USE `TestNLog`; -- Dumping structure for table TestNLog.TblLogrecords CREATE TABLE IF NOT EXISTS `TblLogrecords` ( `Id` int(11) NOT NULL AUTO_INCREMENT, `LogDate` datetime(6) NOT NULL, `LogLevel` varchar(50) NOT NULL, `LogType` varchar(50) DEFAULT NULL, `Logger` varchar(256) NOT NULL, `Message` longtext, `MachineName` varchar(50) DEFAULT NULL, `MachineIp` varchar(50) DEFAULT NULL, `NetRequestMethod` varchar(10) DEFAULT NULL, `NetRequestUrl` varchar(500) DEFAULT NULL, `NetUserIsauthenticated` varchar(10) DEFAULT NULL, `NetUserAuthtype` varchar(50) DEFAULT NULL, `NetUserIdentity` varchar(50) DEFAULT NULL, `Exception` longtext, PRIMARY KEY (`Id`) ) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
網站配置連接
appsettings.json中增加ConectionStrings節(jié)點:
"ConectionStrings": {
"MySqlConnection": "server=192.168.137.10;database=TestNLog;user=root;password=mysql@local"
}
統(tǒng)一日志記錄方法
網站下新建CommonUtils文件夾,添加NLogUtil.cs文件(包含LogType定義):
using NLog;
using NLog.Config;
using System;
using System.ComponentModel;
using System.Linq;
using System.Xml.Linq;
namespace NLogUsage.CommonUtils
{
public enum LogType
{
[Description("網站")]
Web,
[Description("數(shù)據(jù)庫")]
DataBase,
[Description("Api接口")]
ApiRequest,
[Description("中間件")]
Middleware
}
public static class NLogUtil
{
public static Logger dbLogger = LogManager.GetLogger("logdb");
public static Logger fileLogger = LogManager.GetLogger("logfile");
/// <summary>
/// 寫日志到數(shù)據(jù)庫
/// </summary>
/// <param name="logLevel">日志等級</param>
/// <param name="logType">日志類型</param>
/// <param name="message">信息</param>
/// <param name="exception">異常</param>
public static void WriteDBLog(LogLevel logLevel, LogType logType, string message, Exception exception = null)
{
LogEventInfo theEvent = new LogEventInfo(logLevel, dbLogger.Name, message);
theEvent.Properties["LogType"] = logType.ToString();
theEvent.Exception = exception;
dbLogger.Log(theEvent);
}
/// <summary>
/// 寫日志到文件
/// </summary>
/// <param name="logLevel">日志等級</param>
/// <param name="logType">日志類型</param>
/// <param name="message">信息</param>
/// <param name="exception">異常</param>
public static void WriteFileLog(LogLevel logLevel, LogType logType, string message, Exception exception = null)
{
LogEventInfo theEvent = new LogEventInfo(logLevel, fileLogger.Name, message);
theEvent.Properties["LogType"] = logType.ToString();
theEvent.Exception = exception;
fileLogger.Log(theEvent);
}
/// <summary>
/// 確保NLog配置文件sql連接字符串正確
/// </summary>
/// <param name="nlogPath"></param>
/// <param name="sqlConnectionStr"></param>
public static void EnsureNlogConfig(string nlogPath, string sqlConnectionStr)
{
XDocument xd = XDocument.Load(nlogPath);
if (xd.Root.Elements().FirstOrDefault(a => a.Name.LocalName == "targets")
is XElement targetsNode && targetsNode != null &&
targetsNode.Elements().FirstOrDefault(a => a.Name.LocalName == "target" && a.Attribute("name").Value == "log_database")
is XElement targetNode && targetNode != null)
{
if (!targetNode.Attribute("connectionString").Value.Equals(sqlConnectionStr))//不一致則修改
{
//這里暫時沒有考慮dbProvider的變動
targetNode.Attribute("connectionString").Value = sqlConnectionStr;
xd.Save(nlogPath);
//編輯后重新載入配置文件(不依靠NLog自己的autoReload,有延遲)
LogManager.Configuration = new XmlLoggingConfiguration(nlogPath);
}
}
}
}
}
配置NLog依賴注入
網站Program.cs文件中,在CreateHostBuilder方法中添加以下內容:
//using NLog.Web;
.ConfigureLogging(logging => {
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
}).UseNLog(); // NLog: 依賴注入Nlog
完成后如下圖所示:

啟動項目同步連接字符串
修改網站啟動Program.cs中的邏輯:
//using NLogUsage.CommonUtils;
//using Microsoft.Extensions.DependencyInjection;
public static void Main(string[] args)
{
//CreateHostBuilder(args).Build().Run();
var host = CreateHostBuilder(args).Build();
try
{
using (IServiceScope scope = host.Services.CreateScope())
{
IConfiguration configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
//獲取到appsettings.json中的連接字符串
string sqlString = configuration.GetSection("ConectionStrings:MySqlConnection").Value;
//確保NLog.config中連接字符串與appsettings.json中同步
NLogUtil.EnsureNlogConfig("NLog.config", sqlString);
}
//throw new Exception("測試異常");//for test
//其他項目啟動時需要做的事情
//code
NLogUtil.WriteDBLog(NLog.LogLevel.Trace, LogType.Web, "網站啟動成功");
host.Run();
}
catch (Exception ex)
{
//使用nlog寫到本地日志文件(萬一數(shù)據(jù)庫沒創(chuàng)建/連接成功)
string errorMessage = "網站啟動初始化數(shù)據(jù)異常";
NLogUtil.WriteFileLog(NLog.LogLevel.Error, LogType.Web, errorMessage, new Exception(errorMessage, ex));
NLogUtil.WriteDBLog(NLog.LogLevel.Error, LogType.Web, errorMessage, new Exception(errorMessage, ex));
throw;
}
}
修改完成后,如下圖所示:

啟動驗證
啟動項目,可以正常記錄日志到數(shù)據(jù)庫和文件:

以上就是本次介紹的全部相關知識點,感謝大家的學習和對腳本之家的支持。
相關文章
Windows下Visual Studio 2017安裝配置方法圖文教程
這篇文章主要為大家詳細介紹了Windows下Visual Studio 2017安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06
asp.net為網頁動態(tài)添加description描述信息的方法
這篇文章主要介紹了asp.net為網頁動態(tài)添加description描述信息的方法,涉及asp.net動態(tài)操作網頁元素的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-04-04
.NET Core使用Topshelf方式創(chuàng)建Windows服務的全過程記錄
這篇文章主要給大家介紹了關于.NET Core使用Topshelf方式創(chuàng)建Windows服務的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11
.net頁面訪問次數(shù)統(tǒng)計實現(xiàn)原理與代碼
網站訪問量統(tǒng)計、頁面訪問次數(shù)統(tǒng)計,比較實用的一個功能,很多新手朋友都想實現(xiàn),本文處于此目的整理了一些,感興趣的朋友可以了解下2013-01-01
ASP.NET Core Middleware的實現(xiàn)方法詳解
中間件是組裝到應用程序管道中以處理請求和響應的軟件。下面這篇文章主要給大家介紹了關于ASP.NET Core Middleware實現(xiàn)的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2019-01-01

