NLog組件

来源:https://www.cnblogs.com/yiliukejich0614-1234/archive/2018/11/10/9914376.html
-Advertisement-
Play Games

在.NET Core框架中使用NLog組件記錄日誌,寫資料庫,寫文件!!! ...


接觸.net項目的同志們都清楚,最初在項目中記錄日誌常用的是log4net日誌組件,隨著.net框架的不對優化升級,最近新流行的日誌框架nlog,下麵我就對nlog組件說說自己的認知:

下載

通過Nuget安裝NLog

 

 配置

在項目根目錄下新建一個NLog.config(在Nuget包中也可以下載NLog.config包,下載預設的位置是C盤,可能和你的工程不在同一個文件夾,不建議使用),基本目錄結構:targets下麵配置日誌輸出目標及相關參數,rules下麵配置目標輸出規則:

 1 <?xml version="1.0" ?>
 2 <nlog>
 3     <targets>
 4         <target></target>
 5         <target></target>
 6     </targets>
 7     <rules>
 8         <logger></logger>
 9         <logger></logger>
10     </rules>
11 </nlog>
NLog.config

記得在NLog.config的屬性中設置 Copy to Output Directory: Copy always,作用是每次重新生成解決方案的時候都會將改配置文件複製的本地目錄,否則本地找不到配置文件無法將日誌記錄到文件中:

完整的配置文件如下,日誌配置文件儘量單獨創建一個文件:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 3   <targets>
 4     <!--寫入文件-->
 5     <target   xsi:type="File" name="DebugFile"   fileName="Logs\Debug\${shortdate}.log"
 6      layout="日誌時間:${longdate}${newline}日誌來源:${callsite}${newline}日誌級別:${uppercase:${level}}${newline}消息內容:${message}${newline}異常信息:${exception}${newline}==============================================================${newline}" >
 7     </target>
 8     <target   xsi:type="File" name="InfoFile"    fileName="Logs\Info\${shortdate}.log"
 9       layout="日誌時間:${longdate}${newline}日誌來源:${callsite}${newline}日誌級別:${uppercase:${level}}${newline}消息內容:${message}${newline}異常信息:${exception}${newline}==============================================================${newline}" >
10     </target>
11     <target  xsi:type="File"  name="ErrorFile"   fileName="Logs\Error\${shortdate}.log"
12       layout="日誌時間:${longdate}${newline}日誌來源:${callsite}${newline}日誌級別:${uppercase:${level}}${newline}消息內容:${message}${newline}異常信息:${exception}${newline}==============================================================${newline}" >
13     </target>
14 
15     <target xsi:type="Database" name="NewDatabase" >
16       <dbProvider>System.Data.SqlClient</dbProvider>
17       <connectionString>
18         Data Source=127.0.0.1;Initial Catalog=FlightAnalysis;Persist Security Info=true;User ID=sa;Password=111111;       
19       </connectionString>
20       <commandText>
21         insert into OperatorLog(Id,AppName,ModuleName,ProcName,OperationType,Logger,LogMessage,IP,UserName,LogLevel)
22         <!--values(@Id,'','','',0,'','','','','',getdate())-->
23         values(@Id,@AppName,@ModuleName,@ProcName,@OperationType,@Logger,@LogMessage,@IP,@UserName,@LogLevel)
24       </commandText>
25       <parameter name="@Id" layout="${event-context:item=Id}" />
26       <parameter name="@AppName" layout="${event-context:item=AppName}" />
27       <parameter name="@ModuleName" layout="${event-context:item=ModuleName}" />
28       <parameter name="@ProcName" layout="${event-context:item=ProcName}" />
29       <parameter name="@OperationType" layout="${event-context:item=OperationType}" />
30       <parameter name="@Logger" layout="${event-context:item=Logger}" />
31       <parameter name="@LogMessage" layout="${event-context:item=LogMessage}" />
32       <parameter name="@IP" layout="${event-context:item=IP}" />
33       <parameter name="@Longdate" layout="${event-context:item=Longdate}" />
34       <parameter name="@UserName" layout="${event-context:item=UserName}" />
35       <parameter name="@Createdate" layout="${longdate}" />
36       <parameter name="@LogLevel" layout="${level}" />
37     </target>
38   </targets>
39 
40   <rules>
41     <!--根據日誌級別分別寫文件,也可以放一個文件中-->
42     <!--<logger name="DbLogger" levels="Debug,Info,Error" writeTo="MyFile" />-->
43     <logger name="MyLogger" level="Debug" writeTo="DebugFile" />
44     <logger name="MyLogger" level="Info" writeTo="InfoFile" />
45     <logger name="MyLogger" level="Error" writeTo="ErrorFile" />
46     <!--寫資料庫-->
47     <logger name="MyLogger" levels="Trace,Debug,Info,Error"  writeTo="NewDatabase"/>
48   </rules>
49 </nlog>
NLog.config
  • 如在根節點(nlog)配置 internalLogLevel, internalLogFile,可以查看NLog輸出日誌時的內部信息,比如你配置文件有錯誤,很有幫助,不過項目發佈後還是關閉比較好,以免影響效率;
  • 在target外面罩了一個 <target>並且xsi:type為 AsyncWrapper,即表示這條 target 將非同步輸出,這裡我將文件和資料庫日誌非同步輸出;
  • db target內指定了資料庫連接字元串 connectionString,SQL語句,SQL參數,還可以指定資料庫/表創建和刪除的腳本(推薦看NLog源碼示例,這裡不介紹),同時我們自定義了2個參數 action和amount;
  • target參數里有些是NLog內置參數,比如message,level,date,longdate,exception,stacktrace等,NLog在輸出時會自動賦值;
  • layout設置了每條日誌的格式;
  • 在rules節點,我們分別指定了三個target輸出日誌的級別,NLog 用於輸出日誌的級別包括:Trace,Debug,Info,Warn,Error,Fatal,可以設置 minlevel設置最小級別,也可以用 levels定義你所有需要的級別(多個用逗號分隔)。
  • event-context代表自定義的參數。

路由規則(Rules)

   <rules />區域定義了日誌的路由規則。每一個路由表項就是一個<logger />元素。<logger />有以下屬性:

  1. name - 日誌源/記錄者的名字 (允許使用通配符*)
  2. minlevel - 該規則所匹配日誌範圍的最低級別
  3. maxlevel - 該規則所匹配日誌範圍的最高級別
  4. level - 該規則所匹配的單一日誌級別
  5. levels - 該規則所匹配的一系列日誌級別,由逗號分隔。
  6. writeTo - 規則匹配時日誌應該被寫入的一系列目標,由逗號分隔。
  7. final - 標記當前規則為最後一個規則。其後的規則即時匹配也不會被運行

封裝

對NLog.config的Logger進行簡單封裝:

  1  /// <summary>
  2     /// 日誌類,只提供介面
  3     /// 2018-11-6 15:32:01
  4     /// </summary>
  5     public class Logger
  6     {
  7         #region 初始化
  8         //獲取指定的名稱為logger。
  9         //private static NLog.Logger _dblogger = NLog.LogManager.GetLogger("MyLogger");
 10         /// <summary>
 11         /// 日事件間類
 12         /// </summary>
 13         private LogEventInfo lei = new LogEventInfo();
 14         /// <summary>
 15         /// 數據錯誤無法獲取用戶時使用
 16         /// </summary>
 17         public static string DefaultUser = "system";
 18         /// <summary>
 19         /// 預設IP地址
 20         /// </summary>
 21         public static string DefaultIP = "127.0.0.1";
 22         /// <summary>
 23         /// 提供日誌介面和實用程式功能
 24         /// </summary>
 25         private  NLog.Logger _logger = null;
 26         /// <summary>
 27         /// 自定義日誌對象供外部使用
 28         /// </summary>
 29         public static Logger Default { get; private set; }
 30          
 31         private Logger(NLog.Logger logger)
 32         {
 33             _logger = logger;
 34         }
 35         public Logger(string name) : this(LogManager.GetLogger(name))
 36         { }
 37        
 38         static Logger()
 39         {
 40             //獲取具有當前類名稱的日誌程式。
 41             Default = new Logger("MyLogger");
 42         }
 43         #endregion 
 44 
 45         #region Debug
 46         public void Debug(string msg, params object[] args)
 47         {
 48             _logger.Debug(msg, args);
 49         }
 50 
 51         public void Debug(string msg, Exception err)
 52         {
 53             _logger.Debug(err, msg);
 54         }
 55         #endregion
 56 
 57         #region Info
 58         public void Info(string msg, params object[] args)
 59         {
 60             _logger.Info(msg, args);
 61         }
 62 
 63         public void Info(string msg, Exception err)
 64         {
 65             _logger.Info(err, msg);
 66         }
 67         #endregion
 68 
 69         #region Warn
 70         /// <summary>
 71         ///警告
 72         /// </summary>
 73         /// <param name="msg">警告信息</param>
 74         /// <param name="args">動態參數</param>
 75         public void Warn(string msg, params object[] args)
 76         {
 77             _logger.Warn(msg, args);
 78         }
 79         /// <summary>
 80         ///警告
 81         /// </summary>
 82         /// <param name="msg">警告信息</param>
 83         /// <param name="err">異常信息</param>
 84         public void Warn(string msg, Exception err)
 85         {
 86             _logger.Warn(err, msg);
 87         }
 88         #endregion
 89 
 90         #region Trace
 91         /// <summary>
 92         /// 使用指定的參數在跟蹤級別寫入診斷消息
 93         /// </summary>
 94         /// <param name="msg">跟蹤信息</param>
 95         /// <param name="args">動態參數</param>
 96         public void Trace(string msg, params object[] args)
 97         {
 98             _logger.Trace(msg, args);
 99         }
100         /// <summary>
101         /// 使用指定的參數在跟蹤級別寫入診斷消息
102         /// </summary>
103         /// <param name="msg">跟蹤信息</param>
104         /// <param name="args">異常信息</param>
105         public void Trace(string msg, Exception err)
106         {
107             _logger.Trace(err, msg);
108         }
109         #endregion
110 
111         #region Error
112         /// <summary>
113         /// 使用指定的參數在錯誤級別寫入診斷消息。
114         /// </summary>
115         /// <param name="msg">錯誤信息</param>
116         /// <param name="args">動態參數</param>
117         public void Error(string msg, params object[] args)
118         {
119             _logger.Error(msg, args);
120         }
121         /// <summary>
122         /// 使用指定的參數在錯誤級別寫入診斷消息。
123         /// </summary>
124         /// <param name="msg">錯誤信息</param>
125         /// <param name="args">異常信息</param>
126         public void Error(string msg, Exception err)
127         {
128             _logger.Error(err, msg);
129         }
130         #endregion
131 
132         #region Fatal
133         /// <summary>
134         /// 使用指定的參數在致命級別寫入診斷消息。
135         /// </summary>
136         /// <param name="msg">致命錯誤</param>
137         /// <param name="args">動態參數</param>
138         public void Fatal(string msg, params object[] args)
139         {
140             _logger.Fatal(msg, args);
141         }
142         /// <summary>
143         /// 使用指定的參數在致命級別寫入診斷消息。
144         /// </summary>
145         /// <param name="msg">致命錯誤</param>
146         /// <param name="args">異常信息</param>
147         public void Fatal(string msg, Exception err)
148         {
149             _logger.Fatal(err, msg);
150         }
151         /// <summary>
152         /// 刷新所有掛起的日誌消息(在非同步目標的情況下)。
153         /// </summary>
154         /// <param name="timeoutMilliseconds">最大的時間允許沖洗。此後的任何消息都將被丟棄。</param>
155         public void Flush(int? timeoutMilliseconds = null)
156         {
157             if (timeoutMilliseconds != null)
158                 NLog.LogManager.Flush(timeoutMilliseconds.Value);
159 
160             NLog.LogManager.Flush();
161         }
162         #endregion
163 
164 
165         #region Operator日誌寫入
166         /// <summary>
167         /// 寫入日誌信息
168         /// </summary>
169         /// <param name="operatorLogModel">操作信息</param>
170         public void InsOperatorLog(OperatorLogModel operatorLogModel)
171         {
172             var level = LogLevel.Info;
173             if (operatorLogModel.LogLevel == NLog.LogLevel.Trace)
174                 level = LogLevel.Trace;
175             else if (operatorLogModel.LogLevel == NLog.LogLevel.Debug)
176                 level = LogLevel.Debug;
177             else if (operatorLogModel.LogLevel == NLog.LogLevel.Info)
178                 level = LogLevel.Info;
179             else if (operatorLogModel.LogLevel == NLog.LogLevel.Warn)
180                 level = LogLevel.Warn;
181             else if (operatorLogModel.LogLevel == NLog.LogLevel.Error)
182                 level = LogLevel.Error;
183             else if (operatorLogModel.LogLevel == NLog.LogLevel.Fatal)
184                 level = LogLevel.Fatal;
185 
186             if (operatorLogModel.LogMessage.Length > 3000)
187             {
188                 operatorLogModel.LogMessage = operatorLogModel.LogMessage.Substring(0, 3000);
189             }
190             lei.Properties["Id"] = Guid.NewGuid().ToString("D");
191             lei.Properties["AppName"] = operatorLogModel.AppName;
192             lei.Properties["ModuleName"] = operatorLogModel.ModuleName;
193             lei.Properties["ProcName"] = operatorLogModel.ProcName;
194             lei.Properties["OperationType"] = operatorLogModel.OperationType;
195             lei.Properties["Logger"] = operatorLogModel.Logger;
196             lei.Properties["LogMessage"] = operatorLogModel.LogMessage;
197             lei.Properties["IP"] = operatorLogModel.IP ?? DefaultIP;
198             lei.Properties["Longdate"] = operatorLogModel.Longdate;
199             lei.Properties["UserName"] = operatorLogModel.UserName ?? DefaultUser;
200             lei.Properties["Createdate"] = operatorLogModel.Createdate;
201             lei.Level = operatorLogModel.LogLevel;
202             _logger.Log(level, lei);
203         }
204         #endregion 
205     }
Logger

對操作類型進行簡單封裝,也可以自定義:

 1 /// <summary>
 2     /// 操作類型枚舉
 3     /// </summary>
 4     public enum OperationType
 5     {
 6         /// <summary>
 7         /// 保存或添加
 8         /// </summary>
 9         [System.ComponentModel.Description("添加")]
10         ADD,
11         /// <summary>
12         /// 更新
13         /// </summary>
14         [System.ComponentModel.Description("更新")]
15         UPDATE,
16         /// <summary>
17         /// 核銷
18         /// </summary>
19         [System.ComponentModel.Description("核銷")]
20         AUDIT,
21         /// <summary>
22         /// 查看
23         /// </summary>
24         [System.ComponentModel.Description("指派")]
25         ASSIGN,
26         /// <summary>
27         /// 刪除
28         /// </summary>
29         [System.ComponentModel.Description("刪除")]
30         DELETE,
31         /// <summary>
32         /// 讀取/查詢
33         /// </summary>
34         [System.ComponentModel.Description("查詢")]
35         RETRIEVE,
36         /// <summary>
37         /// 登錄
38         /// </summary>
39         [System.ComponentModel.Description("登錄")]
40         LOGIN,
41         /// <summary>
42         /// 查看
43         /// </summary>
44         [System.ComponentModel.Description("查看")]
45         LOOK
46     }
OperationType

自定義類,主要用於綁定數據:

 1 /// <summary>
 2     /// 操作日誌類
 3     /// </summary>
 4     public class OperatorLogModel
 5     {
 6         /// <summary>
 7         /// 自增主鍵ID
 8         /// </summary>
 9         public string Id { get; set; }
10         /// <summary>
11         /// 一級菜單
12         /// </summary>
13         public string AppName { get; set; }
14         /// <summary>
15         /// 二級菜單
16         /// </summary>
17         public string ModuleName { get; set; }
18         /// <summary>
19         /// 本級菜單
20         /// </summary>
21         public string ProcName { get; set; }
22         /// <summary>
23         /// 操作類型
24         /// </summary>
25         public int OperationType { get; set; }
26         /// <summary>
27         /// 日誌文件
28         /// </summary>
29         public string Logger { get; set; }
30         /// <summary>
31         /// 日誌信息
32         /// </summary>
33         public string LogMessage { get; set; }
34         /// <summary>
35         /// IP地址
36         /// </summary>
37         public string IP { get; set; }
38         /// <summary>
39         /// 記錄時間
40         /// </summary>
41         public string Longdate { get; set; }
42         /// <summary>
43         /// 用戶名稱
44         /// </summary>
45         public string UserName { get; set; }
46         /// <summary>
47         /// 日誌級別
48         /// </summary>
49         public NLog.LogLevel LogLevel { get; set; }
50         /

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 話不多說,先乾再說..... 打開pycharm,創建一個關於flask的項目 2.創建一個App的文件包 3.把staic和templates文件包拖進App里 4.把app.py文件改為manager.py文件 5.這裡先停一下,點擊下方Terminal,把我們所需要第三方庫準備好分別是:pip ...
  • 表達式 lambda argument_list: expression argument_list 是參數列表,類似於函數中的參數列表,表現形式多種多樣: a, b a=1, b=2 *args **kwargs a, b=1, *args 空 ...... a, b a=1, b=2 *args ...
  • 前兩篇代碼寫了初始化與查詢,知道了S函數,初始權重矩陣。以及神經網路的計算原理,總這一篇起就是最重要的神經網路的訓練了。 神經網路的訓練簡單點來講就是讓輸出的東西更加接近我們的預期。比如我們輸出的想要是1,但是輸出了-0.5,明顯不是 我們想要的。 誤差=(期望的數值)-(實際輸出),那麼我們的誤差 ...
  • 使用python實現設計模式中的單例模式。單例模式是一種比較常用的設計模式,其實現和使用場景判定都是相對容易的。本文將簡要介紹一下python中實現單例模式的幾種常見方式和原理。一方面可以加深對python的理解,另一方面可以更加深入的瞭解該模式,以便實際工作中能更加靈活的使用單例設計模式。 本文將 ...
  • 剛剛開始學習Java,對Java不是很熟悉,但是自己的興趣挺喜歡Java。現在自己在自學Java做一個小游戲,坦克大戰。 自己現在完成了畫出自己的坦克和坦克的移動方向。希望各位大神指導一下我這個剛剛學Java的新手小白。 我會每完成一個階段,就更新一下博客,跟進一下自己的學習進度。 在做這個坦克大戰 ...
  • 第一章 第一個C#程式 ******************C#程式*************** ①:建立項目:文件-->新建-->項目-->c#-->控制台程式(項目名/文件存儲位置)-->確定 ①:c#程式 namespace:命名空間; 相當於java中的package(聲明包) using ...
  • 三大框架房很好看絕代風華搜狗科技華東師範撒的發空間撒地方是否 ...
  • 註意:本文背景為 Linq to sql 。文中ie指代IEnumerable,iq指代IQueryable。 IQueryable 和 IEnumerable 的區別 IQueryable延時執行;擴展方法接受的是Expression(必須要能轉成sql,否則報錯) IEnumerable延時執行 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...