在項目開發中,日誌系統是系統的一個重要組成模塊,經過在程序中記錄運行日誌、錯誤日誌,可讓咱們對於系統的運行狀況作到很好的掌控。同時,收集日誌不只僅能夠用於診斷排查錯誤,因爲日誌一樣也是大量的數據,經過對這些數據進行集中分析,能夠產生極大的價值。
在微服務的系統架構中,因爲一個系統會被拆成不少個功能模塊,每一個模塊負責不一樣的功能,對於日誌系統的要求也會更高,比較常見的有 EFLK(ElasticSearch + Filebeat + LogStash + Kibana) 方案,而對於咱們這種單體應用來講,因爲程序的代碼比較集中,因此咱們主要採用手寫日誌幫助類或是使用第三方組件的形式進行日誌信息的記錄。html
系列目錄地址:ASP.NET Core 項目實戰
倉儲地址:https://github.com/Lanesra712/Grapefruit.VuCoregit
在 ASP.NET Core 中,巨硬爲咱們提供了一個 ILogger 接口,經過 ILogger 接口,咱們能夠很方便的將日誌信息輸出到控制檯中,不過,在控制檯中查看日誌信息會顯得不太方便,所以,咱們能夠經過實現該接口或是直接使用第三方的框架來實現將日誌信息記錄到別的存儲介質中。github
在 .NET Framework 時代,對於第三方的日誌框架的選擇,絕大多數童鞋首選的都會是 log4net 這一根據 Log4j 移植的日誌框架,不過,因爲 log4net 目前已經接近有3年的時間沒更新了,因此就不在考慮範圍內。綜合比較下官方文檔中推薦的幾款第三方日誌框架,最終仍是選擇 NLog 這一目前使用人數相對來講比較多的框架,畢竟用戶多的話,遇到什麼問題也好找資料。web
一般,咱們會將日誌信息記錄到 txt or log 文件中,雖然你能夠經過修改日誌佈局讓日誌信息具備良好的可讀性,不過在信息多的狀況下查閱時仍是會顯得不太方便。由於不只作到對於錯誤信息作到記錄,還須要記錄程序在運行時的訪問日誌,因此將日誌信息寫入到關係型數據庫中就不是特別合適了。mongodb
而 MongoDB 做爲一個文檔型的 NoSQL 數據庫,相比於傳統的關係型數據庫,NoSQL 數據庫具備更好的擴展性、以及能提供更出色的性能,所以,我最終選擇將日誌信息記錄到 MongoDB 中。固然,最主要的緣由仍是目前在工做中有開始嘗試用 MongoDB 存儲用戶上傳的文件,在找資料的過程當中看到有使用 MongoDB 存儲日誌的案例,Grapefruit.VuCore 既然做爲一個學習項目,因此就要多嘗試嘗試啊。shell
由於是第一次使用 MongoDB,因此咱們須要提早安裝 MongoDB Server,我是直接安裝到個人開發機上(Windows 10),因此這裏只是演示如何在 Windows 上進行 MongoDB 的安裝與配置,如何在 Linux or Docker 中進行安裝配置,我將在後面的文章中進行演示。畢竟,這個項目的最終準備經過 Docker 部署到 Linux 上的,總在 Windows 上玩是不合適滴。數據庫
首先,打開 MongoDB 官網獲取到咱們的安裝包下載地址(MongoDB Community Download),選擇 Server tab 後按照咱們的操做系統選擇安裝包下載便可。json
雙擊下載好的 msi 文件,開始安裝,這裏我選擇 Complete(完整)安裝,若是你想要指定安裝的組件和安裝的位置,你能夠選擇 Custom(自定義安裝)。windows
在 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數據庫中可用。超級帳號,超級權限
當咱們安裝配置好 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 是個好地方,多搜搜,很大可能你就會獲得解決方案。