ASP.NET Core 實戰:使用 NLog 將日誌信息記錄到 MongoDB

来源:https://www.cnblogs.com/danvic712/archive/2019/01/06/10226557.html
-Advertisement-
Play Games

一、前言 在項目開發中,日誌系統是系統的一個重要組成模塊,通過在程式中記錄運行日誌、錯誤日誌,可以讓我們對於系統的運行情況做到很好的掌控。同時,收集日誌不僅僅可以用於診斷排查錯誤,由於日誌同樣也是大量的數據,通過對這些數據進行集中分析,可以產生極大的價值。 在微服務的系統架構中,由於一個系統會被拆成 ...


 一、前言

  在項目開發中,日誌系統是系統的一個重要組成模塊,通過在程式中記錄運行日誌、錯誤日誌,可以讓我們對於系統的運行情況做到很好的掌控。同時,收集日誌不僅僅可以用於診斷排查錯誤,由於日誌同樣也是大量的數據,通過對這些數據進行集中分析,可以產生極大的價值。
  在微服務的系統架構中,由於一個系統會被拆成很多個功能模塊,每個模塊負責不同的功能,對於日誌系統的要求也會更高,比較常見的有 EFLK(ElasticSearch + Filebeat + LogStash + Kibana) 方案,而對於我們這種單體應用來說,由於程式的代碼比較集中,所以我們主要採用手寫日誌幫助類或是使用第三方組件的形式進行日誌信息的記錄。

  系列目錄地址:ASP.NET Core 項目實戰
  倉儲地址:https://github.com/Lanesra712/Grapefruit.VuCore

 二、Step by Step

  1、為什麼選擇 NLog 和 MongoDB

  在 ASP.NET Core 中,巨硬為我們提供了一個 ILogger 介面,通過 ILogger 介面,我們可以很方便的將日誌信息輸出到控制臺中,不過,在控制臺中查看日誌信息會顯得不太方便,因此,我們可以通過實現該介面或是直接使用第三方的框架來實現將日誌信息記錄到別的存儲介質中。

  在 .NET Framework 時代,對於第三方的日誌框架的選擇,絕大多數童鞋首選的都會是 log4net 這一根據 Log4j 移植的日誌框架,不過,由於 log4net 目前已經接近有3年的時間沒更新了,所以就不在考慮範圍內。綜合比較下官方文檔中推薦的幾款第三方日誌框架,最終還是選擇 NLog 這一目前使用人數相對來說比較多的框架,畢竟用戶多的話,遇到什麼問題也好找資料。

  通常,我們會將日誌信息記錄到 txt or log 文件中,雖然你可以通過修改日誌佈局讓日誌信息具有良好的可讀性,不過在信息多的情況下查閱時還是會顯得不太方便。因為不僅做到對於錯誤信息做到記錄,還需要記錄程式在運行時的訪問日誌,所以將日誌信息寫入到關係型資料庫中就不是特別合適了。

  而 MongoDB 作為一個文檔型的 NoSQL 資料庫,相比於傳統的關係型資料庫,NoSQL 資料庫具有更好的擴展性、以及能提供更出色的性能,因此,我最終選擇將日誌信息記錄到 MongoDB 中。當然,最主要的原因還是目前在工作中有開始嘗試用 MongoDB 存儲用戶上傳的文件,在找資料的過程中看到有使用 MongoDB 存儲日誌的案例,Grapefruit.VuCore 既然作為一個學習項目,所以就要多嘗試嘗試啊。

  2、安裝 MongoDB(Windows)

  因為是第一次使用 MongoDB,所以我們需要提前安裝 MongoDB Server,我是直接安裝到我的開發機上(Windows 10),所以這裡只是演示如何在 Windows 上進行 MongoDB 的安裝與配置,如何在 Linux or Docker 中進行安裝配置,我將在後面的文章中進行演示。畢竟,這個項目的最終準備通過 Docker 部署到 Linux 上的,總在 Windows 上玩是不合適滴。

  首先,打開 MongoDB 官網獲取到我們的安裝包下載地址(MongoDB Community Download),選擇 Server tab 後按照我們的操作系統選擇安裝包下載即可。

  雙擊下載好的 msi 文件,開始安裝,這裡我選擇 Complete(完整)安裝,如果你想要指定安裝的組件和安裝的位置,你可以選擇 Custom(自定義安裝)。

  在 MongoDB 之前的版本中,如果我們需要將 MongoDB Server 作為 Windows 服務,需要我們在安裝完成之後進行配置,但是從 MongoDB 4.0 開始,我們就可以在安裝期間直接配置和啟動我們的 MongoDB 作為 Windows 服務了,當我們安裝成功後就會自動啟動 MongoDB 服務。嗯,相信我,如果你上網搜索 Windows 下的 MongoDB 安裝,你會發現 90% 的文章因為是針對 MongoDB 之前版本的,都會在安裝完成之後需要你指定日誌地址、指定存儲地址,配置 Windows 服務啊,而如果你和我一樣,安裝的是 MongoDB 4.0 以上的版本,這些統統都不要,是不是很超值。

  這裡勾選上 Install MongoD as a Service,當我們安裝完成後就會自動啟動 MongoDB 服務,同時,對於這裡的配置項,我們不做任何的改動。

  Service Name:創建的 Windows 服務名稱,如果已經存在了,則需要更換名稱

  Data Directory:存儲數據的目錄

  Log Directory:存儲 MongoDB Log 日誌的目錄

  點擊 Next 之後,安裝程式會詢問你是否需要安裝 MongoDB Compass,MongoDB Compass 是官方的一個可視化管理工具,畢竟總是用黑乎乎的 shell 還是不太方便的,這裡看你自己的需求,決定是否安裝這個工具。

  當我們安裝完成後,MongoDB 的服務也就已經啟動了,此時,你就可以連接上你的 MongoDB Server 了,這裡我是使用 Navicat 進行連接。對於這個服務,你同樣可以在電腦管理中對這個服務進行管理。

  在預設情況下,當我們安裝好 MongoDB 後是不允許遠程訪問以及不存在任何的用戶許可權的。而這些,在我們正式使用中都是需要考慮的。

  首先,配置我們的 MongoDB Server 以允許用戶進行遠程訪問。找到程式安裝路徑下麵的 mongod.cfg 文件(如果你使用的是預設配置,則該文件位於 C:\Program Files\MongoDB\Server\4.0\bin),修改 bindIp 屬性值為 0.0.0.0,重啟 MongoDB 服務,確保 27017 埠外界可以訪問後,則可以遠程訪問我們的 MongoDB 服務。

  當我們允許遠程訪問我們的 MongoDB 服務後,我們更應該為 MongoDB 配置許可權。與我們經常使用的 SQL Server 或是 MySQL 不同,MongoDB 中的許可權是針對每一個資料庫的,也就是說我們需要為使用到的資料庫創建用戶並配置許可權。

  打開 Navicat,連接安裝好的 MongoDB 服務。

  第一步將預設資料庫切換到 admin 資料庫,創建一個管理員用戶,這裡我就將管理員用戶的角色設置為 root 用戶。

//切換到 admin 資料庫
use admin

//創建一個管理員用戶
db.createUser(
   {
     user: "user name",
     pwd: "user password",
     roles: [ { role: "root", db: "admin" } ]
   }
)

  當我們創建好管理員用戶後,我們就可以為資料庫配置用戶與許可權了。右擊連接名稱,新建一個資料庫 GrapefruitVuCore,切換到 GrapefruitVuCore 資料庫後,新建一個可以讀寫的用戶 grapefruit。用戶都創建完成後,關閉我們的 MongoDB 連接。

//切換到 admin 資料庫
use GrapefruitVuCore

//創建一個管理員用戶
db.createUser(
   {
     user: "grapefruit",
     pwd: "grapefruit",
     roles: [ { role: "readWrite", db: "GrapefruitVuCore" } ]
   }
)

  當用戶已經創建完成之後,我們就可以修改配置文件,啟用許可權控制。還是在 mongod.cfg 中,取消 security 節點的註釋,添加授權配置,修改完成後,重啟服務,此時,MongoDB 就必須通過賬戶密碼登錄了。

  當服務重啟之後,如果你還是按照之前的方式連接,則會提示你許可權不足,你需要修改 Navicat 的連接配置。將驗證方式修改成 Password,輸入賬戶、密碼,並指定需要登錄的資料庫,重新連接即可。

  PS:這裡,我使用賬戶、密碼登錄進入 GrapefruitVuCore 後,右側的連接下麵是沒有顯示這個資料庫的,但這個資料庫是真實存在的,不曉得這是個啥問題。

  MongoDB 內置的用戶角色許可權:

  read:允許用戶讀取授權的資料庫

  readWrite:允許用戶讀寫授權的資料庫

  dbAdmin:允許用戶在授權的資料庫中執行管理操作,如索引創建、刪除,查看統計或訪問system.profile

  userAdmin:允許用戶向 system.users 集合寫入,可以在指定資料庫里創建、刪除和管理用戶

  clusterAdmin:只在 admin 資料庫中可用,賦予用戶所有分片和複製集相關函數的管理許可權。

  readAnyDatabase:只在 admin 資料庫中可用,賦予用戶所有資料庫的讀許可權

  readWriteAnyDatabase:只在 admin 資料庫中可用,賦予用戶所有資料庫的讀寫許可權

  userAdminAnyDatabase:只在 admin 資料庫中可用,賦予用戶所有資料庫的 userAdmin 許可權

  dbAdminAnyDatabase:只在 admin 資料庫中可用,賦予用戶所有資料庫的 dbAdmin 許可權。

  root:只在admin資料庫中可用。超級賬號,超級許可權

  3、使用 NLog 記錄日誌信息

  當我們安裝配置好 MongoDB 後,有了存儲日誌信息的介質,我們就可以使用 NLog 來記錄我們的程式日誌信息了。首先,我們需要為項目中添加對於 NLog 的引用,右擊 Grapefruit.WebApi 打開管理 Nuget 程式包頁面或是使用程式包管理器控制台選中預設項目為 Grapefruit.WebApi,添加 NLog、NLog.Web.AspNetCore、NLog.Mongo。

Install-Package NLog
Install-Package NLog.Web.AspNetCore
Install-Package NLog.Mongo

  NLog 和 NLog.Web.AspNetCore 為 ASP.NET Core 添加了對於 NLog 的平臺支持,在 NLog 中,我們可以通過繼承 NLog.Targets.TargetWithLayout 來為 NLog 添加更多的輸出介質支持,而 NLog.Mongo 就是為 NLog 添加輸出日誌信息到 MongoDB 的支持。嗯,嘗試了自己寫,一直有問題,最後還是用的別人寫好的,哈哈哈,水平太菜。

  當我們添加好引用後,在 Grapefruit.WebApi 下添加一個 NLog 的配置文件 nlog.config(文件名全部需要小寫),右鍵 nlog.config,打開屬性視窗,將複製到輸出目錄修改成較新才複製或是總是複製都可以。

  在配置文件中,nlog 節點必須是 xml 文件的根節點,同時包含三個主要的子節點:extensions、targets、rules。

  extensions:當你不僅僅只使用 NLog 這一個基礎的 dll ,並使用了一些基於 NLog 擴展的工具時,你就需要在 extensions 節點下麵添加引用的程式集名稱。例如,這裡,我添加了 NLog.Web.AspNetCore 這個程式集從而達到 NLog 對於 ASP.NET Core 的支持,以及添加了 NLog.Mongo 這個程式集用來將日誌信息輸出到 MongoDB 中。

  targets:targets 節點下包含了我們需要輸出的日誌的信息內容以及日誌信息的佈局,例如,這裡我按照日期輸出兩個文件 nlog-all-date.log 和 nlog-own-date.log,分別記錄所有的日誌信息以及我們自定義記錄的信息。因為我們是需要將日誌信息寫入 MongoDB 中的,這裡我也添加了一個子節點用來設置寫入 MongoDB 資料庫中的數據欄位。

  rules:rules 節點是將需要記錄的日誌級別關聯到記錄日誌的方式上。這裡,我是將只要是 Trace 以上的都進行日誌記錄。

<?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"
      internalLogLevel="info"
      internalLogFile="c:\Temp\GrapefruitVuCore\internal-nlog.txt">

  <!-- enable asp.net core and mongodb layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
    <add assembly="NLog.Mongo"/>
  </extensions>

  <!--internal-nlog:NLog啟動及載入config信息-->
  <!--nlog-all:所有日誌記錄信息-->
  <!--nlog-own:自定義日誌記錄信息-->

  <!-- the targets to write to -->
  <targets>
    <!-- write logs to file  -->
    <target xsi:type="File" name="allfile" fileName="c:\Temp\GrapefruitVuCore\nlog-all-${shortdate}.log"
            layout="日誌記錄時間:${longdate}${newline}日誌級別:${uppercase:${level}}${newline}日誌來源:${logger}${newline}日誌信息:${message}${newline}錯誤信息:${exception:format=tostring}${newline}==============================================================${newline}" />

    <!-- another file log, only own logs. Uses some ASP.NET core renderers -->
    <target xsi:type="File" name="ownFile-web" fileName="c:\Temp\GrapefruitVuCore\nlog-own-${shortdate}.log"
            layout="日誌記錄時間:${longdate}${newline}日誌級別:${uppercase:${level}}${newline}日誌來源:${logger}${newline}日誌信息:${message}${newline}錯誤信息:${exception:format=tostring}${newline}url: ${aspnet-request-url}${newline}action: ${aspnet-mvc-action}${newline}==============================================================${newline}" />

    <!-- write log to mongodb-->
    <target xsi:type="Mongo"
            name="mongo" databaseName="GrapefruitVuCore"
            collectionName="Logs"
            connectionString="mongodb://grapefruit:grapefruit@localhost:27017/GrapefruitVuCore"
            cappedCollectionSize="26214400">
      <property name="LongDate" layout="${longdate}" bsonType="DateTime" />
      <property name="Level" layout="${level}" />
      <property name="Logger" layout="${logger}"/>
      <property name="Message" layout="${message}" />
      <property name="Exception" layout="${exception:format=tostring}" />
      <property name="Url" layout="${aspnet-request-url}" />
      <property name="Action" layout="${aspnet-mvc-action}" />
      <property name="UserName" layout="${windows-identity}" />
    </target>

  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Trace" writeTo="allfile" />

    <!--Skip non-critical Microsoft logs and so log only own logs-->
    <logger name="Microsoft.*" maxLevel="Info" final="true" />
    <!-- BlackHole without writeTo -->
    <logger name="*" minlevel="Trace" writeTo="ownFile-web" />

    <!--Add logs to mongodb-->
    <logger name="*" minlevel="Trace" writeTo="mongo"/>
  </rules>
</nlog>    

  當我們設置好配置文件後就可以在 Program.cs 中啟用 NLog 去記錄日誌。運行我們的項目後,就可以查看記錄的日誌信息了,這裡我在 txt 文件中和 MongoDB 中都有記錄日誌信息,具體看你自己的需求了。

public class Program
{
    public static void Main(string[] args)
    {
        //載入日誌配置信息文件後去捕獲所有的錯誤
        var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
        try
        {
            logger.Info("Init Log API Information");
            CreateWebHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            logger.Error(ex, "Stop Log Information Because Of Exception");
        }
        finally
        {
            LogManager.Shutdown();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();//移除其它已經註冊的日誌處理程式
                logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);//記錄最小日誌級別
            })
            .UseNLog();//註入 NLog 服務
}

  另外,在 appsettings.json 中指定的 Logging 配置會覆蓋任何對於 SetMinimumLevel 方法的調用。因此,你可以刪除配置文件中的 default 屬性,或是根據你自己的需要進行調整。

{
    "Logging": {
        "LogLevel": {
            "Default": "Trace",
            "Microsoft": "Information"
        }
    }
}

 三、總結

   本章主要是演示如何在 Windows 上安裝 MongoDB Server 以及在 ASP.NET Core 項目中使用 NLog 將日誌信息記錄到 MongoDB 中。在我們使用這些這些第三方開源框架時,可能會遇到很多問題,當你無法解決的時候,項目的 Issue 是個好地方,多搜搜,很大可能你就會得到解決方案。


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

-Advertisement-
Play Games
更多相關文章
  • DataGrid中,只要不設置DataGrid的寬度和列寬度,或者將寬度設置為Auto,那麼表格就會根據內容自動調整寬度,以顯示所有內容。但如果是ListView,按以上方法設置,卻達不到列寬自動調整的效果, 列寬在控制項第一次載入的時候已經確定,之後不會隨著某列數據長度的增加和減少而改變列寬。找了很 ...
  • 效果圖:使彈出的列表框緊隨在單元格的下邊緣。 第一次,嘗試在XAML中設置Popup的定位方式:Placement="Mouse"。基本能夠定位,但當在輸入前移動滑鼠,列表框就會隨滑鼠位置顯示,偏離了預定位置。 第二次,嘗試在XAML中設置Popup的定位目標:PlacementTarget="{B ...
  • 最近,開始學習WPF,其UI設計完全顛覆了傳統的設計理念,為程式員提供了極大的自由發揮空間,讓我為之驚嘆,且為之著迷。然而,WPF在國內的熱度卻並不高,大部分貼子都是2012年以前的,出版的圖書也很少,參考的資料不多。為了避免在以後的編程中少走彎路,也防止自己遺忘,在此記錄學習過程遇到的一些問題和感 ...
  • 通過 ASP.NET Core,開發者可輕鬆配置和管理其應用的安全性。 ASP.NET Core 中包含管理身份驗證、授權、數據保護、SSL 強制、應用機密、請求防偽保護及 CORS 管理等等安全方面的處理。 通過這些安全功能,可以生成安全可靠的 ASP.NET Core 應用。而我們這一章就來說道 ...
  • asp.net core參數保護之自定義要保護的參數類型 Intro 為了實現 asp.net core 下的參數保護,擴展了asp.net core 中 DataProtection,可以自動化的保護某些敏感參數,上次推出之後有一些小伙伴反饋希望能保護 返回的參數,本文主要以 為例介紹如何註冊自定 ...
  • 藉助表達式樹感受不一樣的CRUD Intro 最近有個想法,想不寫 sql 語句,做一個類似於 ORM 的東西,自己解析表達式樹,生成要執行的 sql 語句,最後再執行 sql 語句,返回相應結果。 思路解析 常用的 sql 語句基本都有一定的模式,就是 /`DELETE Update SELECT ...
  • 寫在最前:控制台輸出中文亂碼,完全是跟win10操作系統有關,跟VS基本無關,所以網上大量的用VS下載安裝更新的解決辦法是事倍功半的(而且不一定成功),本文的方法只需幾個簡單的步驟,就能解決中文亂碼問題,簡單明快。 本文參照此網友blog:https://blog.csdn.net/C_Khalid ...
  • 一. 依賴註入概述 在軟體設計的通用原則中,SOLID是非常流行的縮略語,它由5個設計原則的首字母構成:單一原則(S)、開放封閉原則(O)、里氏替換原則(L)、介面分離原則(I)、依賴反轉原則(D)。本篇介紹依賴反轉原則以及在ASP.NET Core中的實現。 直接依賴是指:當一個類需要另一個類協作 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...