[C#] 將NLog輸出到RichTextBox,併在運行時動態修改日誌級別過濾

来源:https://www.cnblogs.com/zyl910/archive/2018/04/21/cs_nlog_richtextboxtarget_editrule.html
-Advertisement-
Play Games

作者: "zyl910" 一、緣由 NLog是一個很好用的日誌類庫。利用它,可以很方便的將日誌輸出到 調試器、文件 等目標,還支持輸出到窗體界面中的RichTextBox等目標。 而且它還支持在運行時修改配置,例如可用於實現這樣的需求——在界面上做個下拉框,可動態調整RichTextBox的日誌級別 ...


作者: zyl910

一、緣由

NLog是一個很好用的日誌類庫。利用它,可以很方便的將日誌輸出到 調試器、文件 等目標,還支持輸出到窗體界面中的RichTextBox等目標。
而且它還支持在運行時修改配置,例如可用於實現這樣的需求——在界面上做個下拉框,可動態調整RichTextBox的日誌級別過濾。

二、輸出到RichTextBox

2.1 辦法

首先,項目中需要加入NLog的程式包。既用 NuGet 下載這些包——

  • NLog
  • NLog.Config
  • NLog.Windows.Forms

隨後便可修改 NLog.config 文件,增加RichTextBox目標了。
這時有2點需註意——

  1. RichTextBox的target配置中,formName是“RichTextBox所在窗體的類名”,controlName是“該窗體中的RichTextBox控制項名”。區分大小寫,需要完全一致。
  2. 在NLog載入配置前,需要確保該RichTextBox已存在。

若以上2條中有任意一條不符時,NLog會自動彈出一個含RichTextBox的小視窗來顯示日誌,而不是你所指定的RichTextBox。
這2中,第1條是很容易實現的,就是第2條稍微麻煩一點。它的處理訣竅是,不要做靜態初始化,而是要等到窗體的Load事件時才初始化Logger對象,且保證該窗體是首個使用NLog的類。這是因為NLog是在首次被使用時,才載入配置文件的。

即不能這樣寫——

private static Logger logger = LogManager.GetCurrentClassLogger();

而是要這樣寫——

private static Logger logger = null;

private void MainForm_Load(object sender, EventArgs e) {
    if (null == logger) {
        logger = LogManager.GetCurrentClassLogger();
    }
}

2.2 範例

假設窗體名(formName)為MainForm,RichTextBox控制項名為rtbLog。那麼 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"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">

    <targets async="true">
        <target xsi:type="Debugger" name="debugger" layout="${longdate} ${level:uppercase=true} [${threadname}] ${message} ${onexception:${exception:format=tostring} ${newline}}" />
        <target xsi:type="File" name="f"
                fileName="${basedir}/logs/${shortdate}.log"
                layout="${longdate} ${level:uppercase=true} [${threadname}] ${message} ${onexception:${exception:format=tostring} ${newline}}"
                encoding="utf-8" />
        <target xsi:type="RichTextBox" name="richTextBox"
          layout="${longdate} ${level:uppercase=true} [${threadname}] ${message} ${onexception:${exception:format=Message}}"
          autoScroll="true"
          maxLines="1000"
          formName="MainForm"
          controlName="rtbLog"
          useDefaultRowColoringRules="false" />
    </targets>

    <rules>
        <logger name="*" minlevel="Debug" writeTo="debugger" />
        <logger name="*" minlevel="Info" writeTo="f" />
        <logger name="*" minlevel="Info" writeTo="richTextBox" />
    </rules>
</nlog>

上面的配置文件還演示了這些功能——

  • 將日誌輸出到調試器(Debugger)。
  • 將日誌輸出到文件(File)。且是log子目錄下每天一個文件(fileName="${basedir}/logs/${shortdate}.log"),編碼指明為utf-8(encoding="utf-8")避免gbk外字元亂碼。
  • 採用不同的日誌字元串格式(layout)。RichTextBox只顯示異常消息(Message),而不顯示包含錯誤棧的異常詳情(tostring)。
  • 目標都是非同步模式(<targets async="true">)。
  • 支持自動重新載入配置(autoReload="true")。

三、動態修改日誌級別

3.1 需求

首先,NLog支持自動重新載入配置的機制,可參考上面配置的 autoReload="true"。即修改NLog.config的配置,會對運行中的程式也是生效的,這樣便無需重啟程式了。

但對於RichTextBox輸出的日誌來說,上述機制還不夠方便。最好是界面上提供一些直接調整日誌配置的功能。例如——RichTextBox最初的最小日誌級別為Info級,當想看詳細日誌時,可點界面的下拉框,便可將最小日誌級別改為Debug級。

3.2 辦法

NLog提供了動態修改配置的介面。

調用 LogManager.Configuration ,可得到 LoggingConfiguration 對象。它就是當前的配置數據。
然後可通過 LoggingConfiguration.LoggingRules,獲取日誌規則集合(即 <rules>)。這樣便能就行修改對應的配置了。
最後別忘了調 LogManager.ReconfigExistingLoggers,使修改的配置生效。

3.3 範例

可這樣實現下拉選擇RichTextBox日誌級別過濾的功能——在窗體放一個名為 cboLogLevelMin 的下拉框,配好屬性,然後處理它的 SelectedIndexChanged 事件。

private void cboLogLevelMin_SelectedIndexChanged(object sender, EventArgs e) {
    if (null == cboLogLevelMin.SelectedItem) return;
    String str = cboLogLevelMin.SelectedItem.ToString();    // 獲取日誌級別.
    LogLevel lv = LogLevel.Info;    // 若選擇的值無效, 則當作 Info級.
    try {
        lv = LogLevel.FromString(str);
    } catch (Exception ex) {
        if (null == logger) return;
        logger.Debug(ex, "LogLevel.FromString fail!");
    }
    LoggingConfiguration lc = LogManager.Configuration;    // 取得 NLog 配置.
    LoggingRule lr = lc.LoggingRules.FirstOrDefault(
        r => r.Targets.Any(
            t => "richTextBox" == t.Name
        )
    );    // 查找 RichTextBox 所用的 LoggingRule .
    if (null != lr) {
        lc.LoggingRules.Remove(lr);    // 刪除舊的 LoggingRule .
    }
    lc.AddRule(lv, LogLevel.Fatal, "richTextBox");    // 新增 LoggingRule .
    LogManager.ReconfigExistingLoggers();    // 使配置生效.
}

參考文獻

(完)


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

-Advertisement-
Play Games
更多相關文章
  • 直接插入排序演算法思想: 排序區間 ; 在排序的過程中,整個排序區間被分為兩個子區間: 有序區 和無序區 ; 共進行n-1趟排序,每趟排序都是把無序區的 插到有序區的合適位置上。 ArrayList實現: java int[] a={ 50, 15, 18, 8, 40, 51, 60, 1, 1, ...
  • 操作系統 : CentOS7.3.1611_x64 Python 版本 : 2.7.5 問題描述 編碼過程中有時候會遇到在多個源文件中存在同一個變數名(比如 : writeBuffer),需要替換為新的變數名(比如 : write_buffer)的問題。 怎麼能方便快捷的解決該問題呢? 解決方案 使 ...
  • 配置指令 管理會話存儲介質 確定如何存儲會話信息 session. save_handler = files(平面文件)mm(共用記憶體)sqlite(SQLite資料庫)user(自定義) 設置會話文件路徑 如果session.save_handler = files,則session.save_p ...
  • 在做這個SDRAM控制器之前,博主有一個疑問,對於學生來說,是否有必要學慣用純Verilog寫一個SDRAM控制器?因為目前X家和A家都有了DDR IP Core,對於要實現一個應用可以直接調用IP Core,只需要對其介面操作即可。對於開發者來說,與其費時費力用Verilog去寫一個性能差而且老的 ...
  • 轉載請註明出處:http://www.cnblogs.com/qm-article/p/8903893.html 一、介紹 在介紹該源碼之前,先來瞭解一下鏈表,接觸過數據結構的都知道,有種結構叫鏈表,當然鏈表也分多種,如常見的單鏈表、雙鏈表等,單鏈表結構如下圖所示(圖來自百度) 有一個頭結點指著下一 ...
  • 內容:流的分類,文件寫入(位元組輸出流),異常處理,獲取一個文件夾下的特定文件集合 位元組流的抽象基類:InputStream,OutputStream字元流的抽象基類:Reader,Writer由這四個類派生出來的子類名稱都是以父類名作為子類名的尾碼。如:InputStream的子類FileInput ...
  • 第一個 Python 程式 目標 第一個 程式 與 版本簡介 執行 程式的三種方式 解釋器 —— / 互動式 —— 集成開發環境 —— 01. 第一個 程式 1.1 Python 源程式的基本概念 1. Python 源程式就是 一個特殊格式的文本文件 ,可以 使用任意文本編輯軟體 做 的開發 2. ...
  • C++多態 Polymorphism 本文為C++官網對多態闡述:http://www.cplusplus.com/doc/tutorial/polymorphism/ 在瞭解多態前需具備如下知識:類、結構體、友元和繼承。 指向基類的指針 先來看一個基礎例子 1 // pointers to bas ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...