NLog簡介
NLog是一個簡單靈活的.NET日志記錄類庫,NLog的API非常類似於log4net,配置方式非常簡單。支持多種形式輸出日志:文本文件、系統日志、數據庫、控制台、郵箱等
1.NLog簡介
在nuget控制台輸入安裝nlog命令: Install-Package NLog.Config
Nlog配置的方式常用的有兩種
1.直接在使用應用程序配置文件或者web的配置文件(app.config / web.config)
2.NLog.config 這個是比較好的一個形式(推薦)
配置文件中的主要標簽是:
targets和rules:
<targets /> - 定義日志的目標/輸出,下級是<target>
<rules /> - 定義日志的路由規則,下級是<logger>
2.標簽介紹
<nlog>標簽
autoReload 修改配置文件后是否允許自動加載無須重啟程序
throwExceptions 內部日志系統拋出異常(建議throwExceptions的值設為“false”,這樣由於日志引發的問題不至於導致應用程序的崩潰。)
internalLogLevel 可選Trace|Debug|Info|Warn|Error|Fatal決定內部日志的級別 Off 關閉
internalLogFile 把內部的調試和異常信息都寫入指定文件里
<targets>標簽
<target />定義了日志的輸出,可以設置文件名稱和格式,輸出方式。
name 自定義該target的名字,可供rule規則里使用
type 定義類型,官方提供了很多可選類型,常用的還是 File \Database \Colored Console\ Mail
layouts 用來規定布局樣式,語法“${屬性}”,可以把上下文信息插入到日志中,官方提供的可以用的屬性見文末附錄
<rules>標簽
<logger/>定義日志的記錄規則,記錄范圍
name 記錄者的名字
minlevel 最低級別
maxlevel 最高級別
level 單一日志級別
levels 一系列日志級別,由逗號分隔。
<variable>標簽
變量定義 <!-- 定義變量var1--> <variable name="var1" value="${basedir}/logs"/> <targets> <!-- 使用變量var1--> <target name="File" xsi:type="File" fileName="${var1}/${shortdate}.txt"/> </targets>
3.一個簡單的栗子
把日志記錄到彩色控制台,log文本文件和mysql數據庫。首先添加Nlog.config文件如下,放在控制台項目的bin/debug目錄下

<?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="console" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false" layout="${longdate}|${pad:padding=5:inner=${level:uppercase=true}}|${message}" > <highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" /> <highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" /> <highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" /> <highlight-row condition="level == LogLevel.Error" foregroundColor="Red" /> <highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" /> </target> <!--寫入log文本文件--> <target name="file" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard"> <target xsi:type="File" fileName="${basedir}/logs/nlog/AT___${shortdate}.log" layout="----------------日志記錄開始----------------${newline}【日志時間】:${longdate} ${newline}【日志級別】:${level:uppercase=true}${newline}【異常相關信息】${newline}${message}${newline}${newline}${newline}" /> </target> <!--寫入mysql數據庫--> <target name="db" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard"> <target type="Database" dbProvider="MySql.Data.MySqlClient" connectionString="server=10.0.10.66;port=3306;database=logedemo;uid=root;pwd=123321;SslMode=none"> <commandText> INSERT INTO tbLog(Timestamp,Level,Message,StackTrace) VALUES(@time_stamp, @level, @message, @stacktrace); </commandText> <!--database connection parameters--> <parameter name="@time_stamp" layout="${date}" /> <parameter name="@level" layout="${level:uppercase=true}" /> <parameter name="@message" layout="${message}" /> <parameter name="@stacktrace" layout="${stacktrace}" /> </target> </target> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="console" /> <logger name="*" minlevel="Info" writeTo="db" /> <logger name="*" minlevel="Debug" writeTo="file" /> </rules> </nlog>
LogHelper是通過拓展String實現的一個簡單的helper,調用代碼如下:

class Program { static void Main(string[] args) { Console.WriteLine("---------------------------begin"); "helper logs debug".Debug(); "helper logs info".Info(); "helper logs warn".Warn(); "helper logs error".Error(); "helper logs fatal".Fatal(); Console.WriteLine("---------------------------end"); Console.ReadKey(); } } public static class LogHelper { private static ILogger logger = GetLogger(); private static ILogger GetLogger() { LogManager.Configuration = new XmlLoggingConfiguration(Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"\Nlog.config")); return LogManager.GetCurrentClassLogger(); } /// <summary> /// 調試 /// </summary> /// <param name="debug"></param> public static void Debug(this string debug) { logger.Debug(debug); } /// <summary> /// 信息 /// </summary> /// <param name="info"></param> public static void Info(this string info) { logger.Info(info); } /// <summary> /// 警告 /// </summary> /// <param name="warn"></param> public static void Warn(this string warn) { logger.Warn(warn); } /// <summary> /// 錯誤 /// </summary> /// <param name="error"></param> public static void Error(this string error) { logger.Error(error); } /// <summary> /// 嚴重錯誤 /// </summary> /// <param name="fatale"></param> public static void Fatal(this string fatal) { logger.Fatal(fatal); } /// <summary> /// 跟蹤 /// </summary> /// <param name="trace"></param> public static void Trace(this string trace) { logger.Trace(trace); } }
記錄效果如下:
控制台中使用彩色高亮展示日志信息
mysql中效果如下
log文件效果如下
這里的異常信息只是簡單的一句話,在實際開發中我們可以把很多內容添加到異常相關信息中,如下是一個.Net WebApi的異常日志的顯示效果:
過濾器代碼如下

/// <summary> /// 異常處理過濾器 /// </summary> public class ErrorHandleAttribute : ExceptionFilterAttribute { /// <summary> /// 異常處理過濾器 /// </summary> /// <param name="actionExecutedContext"></param> public override void OnException(HttpActionExecutedContext actionExecutedContext) { //獲取客戶端Ip string clientIP = GetHostAddress();//主機Ip //獲取httpmethod string strHttpMethod = actionExecutedContext.Request.Method.ToString(); //請求的url string url = actionExecutedContext.Request.RequestUri.AbsoluteUri; //異常信息 string exceptionMsg = actionExecutedContext.Exception.Message; //異常定位 string exceptionPosition = actionExecutedContext.Exception.StackTrace.Split(new string[] { "\r\n" }, StringSplitOptions.None).Where(s => !string.IsNullOrWhiteSpace(s)).First().Trim(); //string stack //記錄的message string message = $"----1.[客戶端Ip]:{ clientIP} " + Environment.NewLine + $"----2.[請求方法]:{ strHttpMethod} " + Environment.NewLine + $"----3.[請求url]:{ url }" + Environment.NewLine + $"----4.[異常信息]:{exceptionMsg} " + Environment.NewLine + $"----5.[異常定位]:{exceptionPosition}"; //Log4net記錄 LogHelper.WriteErrorLog("", message); //nlog記錄 NlogHelper.WriteErrorLog(message); actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse( HttpStatusCode.InternalServerError, new { msg = "服務器忙,請稍后再試!" }); } /// <summary> /// 獲取客戶端IP地址(無視代理) /// </summary> /// <returns>若失敗則返回回送地址</returns> public static string GetHostAddress() { string userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; if (string.IsNullOrEmpty(userHostAddress)) { if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null) userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(',')[0].Trim(); if (string.IsNullOrEmpty(userHostAddress)) { userHostAddress = HttpContext.Current.Request.UserHostAddress; } } //最后判斷獲取是否成功,並檢查IP地址的格式(檢查其格式非常重要) if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress)) { return userHostAddress; } return "127.0.0.1"; } /// <summary> /// 檢查IP地址格式 /// </summary> /// <param name="ip"></param> /// <returns></returns> public static bool IsIP(string ip) { return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); } }
4.layout參數列表
${appdomain} | 當前應用程序域 |
${assembly-version} | 應用程序 |
${basedir} | 應用程序域的基本目錄。 |
${callsite} | (類名稱、方法名稱和相關信息的源信息)。 |
${counter} | 數值 |
${date} | 當前日期和時間。 |
${environment} | 環境變量 |
${exception} | exception信息 |
${guid} | GUID |
${identity} | 線程標識信息 |
${level} | 級別。 |
${log4jxmlevent} | XML事件描述 |
${logger} | 記錄器的名字 |
${longdate} | 日期和時間的格式分類yyyy-MM-dd HH:mm:ss.ffff。 |
${machinename} | 名稱 |
${message} | 消息 |
${newline} | 文字換行 |
${processid} | 當前進程標識符 |
${processinfo} | 運行信息 |
${processname} | 當前進程的名稱。 |
${processtime} | 該時間過程中格式HH:MM:ss.mmm。 |
${shortdate} | 短時間 格式YYYY-MM-DD。 |
${threadid} | 當前線程的標識符。 |
${threadname} | 當前線程。 |
${ticks} | 當前日期和時間。 |
${time} | 24小時格式HH:MM:ss.mmm。 |
${var} | {$var}-提供新的變量(4.1) |
補充:下邊是一個分級別記錄的Nlog.Config,這個配置文件和上邊的LogHelper可以一起使用。

<?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="Debug" xsi:type="file" fileName="F:/Logs/Debug/${shortdate}-Debug.log" layout="----------------日志記錄開始----------------${newline}【日志時間】:${longdate} ${newline}【日志級別】:${level:uppercase=true}${newline}【相關信息】${newline}${message}${newline}${newline}${newline}" /> <target name="Warn" xsi:type="file" fileName="F:/Logs/Warn/${shortdate}-Warn.log" layout="----------------日志記錄開始----------------${newline}【日志時間】:${longdate} ${newline}【日志級別】:${level:uppercase=true}${newline}【相關信息】${newline}${message}${newline}${newline}${newline}" /> <target name="Error" xsi:type="file" fileName="F:/Logs/Error/${shortdate}-Error.log" layout="----------------日志記錄開始----------------${newline}【日志時間】:${longdate} ${newline}【日志級別】:${level:uppercase=true}${newline}【相關信息】${newline}${message}${newline}${newline}${newline}" /> <target name="Info" xsi:type="file" fileName="F:/Logs/Info/${shortdate}-Info.log" layout="----------------日志記錄開始----------------${newline}【日志時間】:${longdate} ${newline}【日志級別】:${level:uppercase=true}${newline}【相關信息】${newline}${message}${newline}${newline}${newline}" /> <target name="Fatal" xsi:type="file" fileName="F:/Logs/Fatal/${shortdate}-Fatal.log" layout="----------------日志記錄開始----------------${newline}【日志時間】:${longdate} ${newline}【日志級別】:${level:uppercase=true}${newline}【相關信息】${newline}${message}${newline}${newline}${newline}" /> <target name="Trace" xsi:type="file" fileName="F:/Logs/Trace/${shortdate}-Trace.log" layout="----------------日志記錄開始----------------${newline}【日志時間】:${longdate} ${newline}【日志級別】:${level:uppercase=true}${newline}【相關信息】${newline}${message}${newline}${newline}${newline}" /> </targets> <rules> <logger name="*" levels="Info" writeTo="Info" /> <logger name="*" levels="Warn" writeTo="Warn" /> <logger name="*" levels="Trace" writeTo="Trace" /> <logger name="*" levels="Debug" writeTo="Debug" /> <logger name="*" levels="Error" writeTo="Error" /> <logger name="*" levels="Fatal" writeTo="Fatal" /> </rules> </nlog>
參考文獻:
1.https://www.cnblogs.com/HQFZ/p/5832613.html
2.https://blog.csdn.net/lglgsy456/article/details/36642155
3.https://www.cnblogs.com/fuchongjundream/p/3936431.html