本文歡迎轉載,做者原創地址:http://www.cnblogs.com/DjlNet/p/7604340.htmlhtml
近日,天氣漸冷,懶惰的腦蟲又開始做祟了,致使近日內功修煉遲遲未能進步,依然徘徊在XXX框架學習當中,固然了並非說這種學習很差,只是感受收益不高,可是今天博主依然仍是老酒新裝,把在單體應用架構當中對於Log這塊使用最平凡的兩款日誌組件拿來講道一二,也是對後面框架集成作好鋪墊的準備....其實也算是對框架學習系列的一個湊數行爲,捂臉.....git
按照國際慣例,這裏仍是給出各自的官方地址,Log4net:https://logging.apache.org/log4net/ , Nlog :http://nlog-project.org/,這裏博主可能就不會去一一解釋各類組件當中的重要元素、關鍵類以及使用API和關於Provider的配置了,這裏着重仍是博主本身工做或者項目當中常規使用到的一些東西備份記錄,因此想看詳細解讀的同窗,能夠移步去官方連接或者搜索園中其餘相關文,因此老司機就可能須要繞道兒了....其實就目前項目使用log組件程度而言,多半是用來記錄應用程序日誌的,且大多數是以文本的方式(也就是txt、log)來記錄日誌,方便在程序上線以後免於遠程調試以及很差跟蹤的問題,那麼問題來了,應用程序你們也知道日積月累的產生的日誌量,確定是不少的,那麼爲了方便咱們好去跟蹤問題,應該怎麼樣去分類存儲日誌文件方便開發者追溯問題!!!多說一句,當咱們的API服務成百上千,咱們的應用程序或者系統幾十上百,那麼這個時候咱們的日誌還處於單體應用體系的話,一條完整的服務調用連的日誌跟蹤就是一個大麻煩,亦或者須要統籌各自應用的異常行爲和錯誤數據等等,因此當咱們的形態達到必定規模以後,咱們須要的就是分佈式日誌處理分析的平臺,關鍵詞:ELK 請自行搜索,感嘆社區輪子的威力,不過那都是後話了.....github
這裏咱們按照上面的需求和限定範圍得知,log4net 日誌框架組件歷史由來已久且在使用性和或靈活性上面都頗爲好評,衆所周知咱們的日誌等級分爲: DEBUG、INFO、WARN、ERROR、FATAL,日誌等級由低到高的一個過程,因此這個等級分類也是咱們須要參考的一個點,其次就是須要按照年份、月份來劃分文件夾,最後纔是以日期做爲文件名,log做爲文件後綴名(txt同樣),按照如上所說須要配置的 log4net.config 配置以下:sql
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <!--添加自定義節點:log4net type:解析類名,程序集名(log4net.dll)--> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <log4net> <root> <!--<level value="DEBUG"/>--> <!--控制級別,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--> <!--好比定義級別爲INFO,則INFO級別向下的級別,好比DEBUG日誌將不會被記錄--> <level value="ALL"/> <!--根據log級別記錄到不一樣的日誌文件--> <appender-ref ref="DebugLogger" /> <appender-ref ref="InfoLogger" /> <appender-ref ref="WarnLogger" /> <appender-ref ref="ErrorLogger" /> <appender-ref ref="FatalLogger" /> </root> <!--Debug文件日誌記錄器--> <appender name="DebugLogger" type="log4net.Appender.RollingFileAppender"> <!--日誌存放文件夾--> <file value="Log\Debug\"/> <!--是否追加到文件--> <appendToFile value="true" /> <!--記錄日誌寫入文件時,不鎖定文本文件,防止多線程時不能寫Log,官方說線程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--使用UTF-8編碼--> <Encoding value="UTF-8" /> <!--最多產生的日誌文件數,超過則只保留最新的n個。設定值value="-1"爲不限文件數--> <maxSizeRollBackups value="-1"/> <!--是否只寫到一個文件中--> <StaticLogFileName value="false"/> <!--按照何種方式產生多個日誌文件(日期[Date],文件大小[Size],混合[Composite])--> <rollingStyle value="Date" /> <!--日期的格式,天天換一個文件記錄,如不設置則永遠只記錄一天的日誌,需設置--> <param name="datePattern" value="yyyy/yyyy-MM/yyyy-MM-dd.'log'" /> <!--過濾設置,LevelRangeFilter爲使用的過濾器。--> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="DEBUG" /> <levelMax value="DEBUG" /> </filter> <!--日誌格式--> <layout type="log4net.Layout.PatternLayout"> <!-- 輸出格式 日期,日誌級別,消息,換行--> <param name="ConversionPattern" value="%date [%-5p] %message%n" /> </layout> </appender> <!--InfoLog文件日誌記錄器--> <appender name="InfoLogger" type="log4net.Appender.RollingFileAppender"> <!--日誌存放文件夾--> <file value="Log\Info\"/> <!--是否追加到文件--> <appendToFile value="true" /> <!--記錄日誌寫入文件時,不鎖定文本文件,防止多線程時不能寫Log,官方說線程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--使用UTF-8編碼--> <Encoding value="UTF-8" /> <!--最多產生的日誌文件數,超過則只保留最新的n個。設定值value="-1"爲不限文件數--> <maxSizeRollBackups value="-1"/> <!--是否只寫到一個文件中--> <StaticLogFileName value="false"/> <!--按照何種方式產生多個日誌文件(日期[Date],文件大小[Size],混合[Composite])--> <rollingStyle value="Date" /> <!--日期的格式,天天換一個文件記錄,如不設置則永遠只記錄一天的日誌,需設置--> <param name="datePattern" value="yyyy/yyyy-MM/yyyy-MM-dd.'log'" /> <!--過濾設置,LevelRangeFilter爲使用的過濾器。--> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="INFO" /> <levelMax value="INFO" /> </filter> <!--日誌格式--> <layout type="log4net.Layout.PatternLayout"> <!-- 輸出格式 日期,日誌級別,消息,換行--> <param name="ConversionPattern" value="%date [%-5p] %message%n" /> </layout> </appender> <!--WarnLog文件日誌記錄器--> <appender name="WarnLogger" type="log4net.Appender.RollingFileAppender"> <!--日誌存放文件夾--> <file value="Log\Warn\"/> <!--是否追加到文件--> <appendToFile value="true" /> <!--記錄日誌寫入文件時,不鎖定文本文件,防止多線程時不能寫Log,官方說線程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--使用UTF-8編碼--> <Encoding value="UTF-8" /> <!--最多產生的日誌文件數,超過則只保留最新的n個。設定值value="-1"爲不限文件數--> <maxSizeRollBackups value="-1"/> <!--是否只寫到一個文件中--> <StaticLogFileName value="false"/> <!--按照何種方式產生多個日誌文件(日期[Date],文件大小[Size],混合[Composite])--> <rollingStyle value="Date" /> <!--日期的格式,天天換一個文件記錄,如不設置則永遠只記錄一天的日誌,需設置--> <param name="datePattern" value="yyyy/yyyy-MM/yyyy-MM-dd.'log'" /> <!--過濾設置,LevelRangeFilter爲使用的過濾器。--> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="WARN" /> <levelMax value="WARN" /> </filter> <!--日誌格式--> <layout type="log4net.Layout.PatternLayout"> <!-- 輸出格式 日期,日誌級別,消息,換行--> <param name="ConversionPattern" value="%date [%-5p] %message%n" /> </layout> </appender> <!--ErrorLog文件日誌記錄器--> <appender name="ErrorLogger" type="log4net.Appender.RollingFileAppender"> <!--日誌存放文件夾--> <file value="Log\Error\"/> <!--是否追加到文件--> <appendToFile value="true" /> <!--記錄日誌寫入文件時,不鎖定文本文件,防止多線程時不能寫Log,官方說線程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--使用UTF-8編碼--> <Encoding value="UTF-8" /> <!--最多產生的日誌文件數,超過則只保留最新的n個。設定值value="-1"爲不限文件數--> <maxSizeRollBackups value="-1"/> <!--是否只寫到一個文件中--> <StaticLogFileName value="false"/> <!--按照何種方式產生多個日誌文件(日期[Date],文件大小[Size],混合[Composite])--> <rollingStyle value="Date" /> <!--日期的格式,天天換一個文件記錄,如不設置則永遠只記錄一天的日誌,需設置--> <param name="datePattern" value="yyyy/yyyy-MM/yyyy-MM-dd.'log'" /> <!--過濾設置,LevelRangeFilter爲使用的過濾器。--> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="ERROR" /> <levelMax value="ERROR" /> </filter> <!--日誌格式--> <layout type="log4net.Layout.PatternLayout"> <!-- 輸出格式 日期,日誌級別,消息,換行--> <param name="ConversionPattern" value="%date [%-5p] %message%n" /> </layout> </appender> <!--FatalLog文件日誌記錄器--> <appender name="FatalLogger" type="log4net.Appender.RollingFileAppender"> <!--日誌存放文件夾--> <file value="Log\Fatal\"/> <!--是否追加到文件--> <appendToFile value="true" /> <!--記錄日誌寫入文件時,不鎖定文本文件,防止多線程時不能寫Log,官方說線程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--使用UTF-8編碼--> <Encoding value="UTF-8" /> <!--最多產生的日誌文件數,超過則只保留最新的n個。設定值value="-1"爲不限文件數--> <maxSizeRollBackups value="-1"/> <!--是否只寫到一個文件中--> <StaticLogFileName value="false"/> <!--按照何種方式產生多個日誌文件(日期[Date],文件大小[Size],混合[Composite])--> <rollingStyle value="Date" /> <!--日期的格式,天天換一個文件記錄,如不設置則永遠只記錄一天的日誌,需設置--> <param name="datePattern" value="yyyy/yyyy-MM/yyyy-MM-dd.'log'" /> <!--過濾設置,LevelRangeFilter爲使用的過濾器。--> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="FATAL" /> <levelMax value="FATAL" /> </filter> <!--日誌格式--> <layout type="log4net.Layout.PatternLayout"> <!-- 輸出格式 日期,日誌級別,消息,換行--> <param name="ConversionPattern" value="%date [%-5p] %message%n" /> </layout> </appender> </log4net> </configuration>
上面的配置樓主已經親測能夠是使用了,且已經按照咱們的需求按照日誌等級(這裏是經過logger對應的filter來控制的)、年份、月份、日期這個要點分類存儲了日誌文件,且不一樣等級的日誌文件存儲在對應等級的文件夾下面,配置文件當中有較爲詳細的說明能夠參考本身的需求自定義配置,例如修改成本身的layout展現效果等等,文件存儲效果以下圖:
從上圖就能夠看出基本知足了咱們平常單體應用開發的需求了......這裏貼出文件配置也是博主藉此備份一下,往後好找....至於說怎麼使用、異步仍是同步那就看各位同窗本身把握和封裝了....,若是哪位老鐵有更好的方式能夠告知一二!!!數據庫
需求仍是同上邏輯,且咱們使用NLog依然仍是以file做爲基礎實現配置,話很少說Nlog.config 完整配置以下:apache
<?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" throwConfigExceptions="true"> <!-- optional, add some variables https://github.com/nlog/NLog/wiki/Configuration-file#variables --> <!--<variable name="myvar" value="myvalue"/>--> <variable name="year" value="${date:format=yyyy}"/> <variable name="year_month" value="${date:format=yyyy-MM}"/> <!-- See https://github.com/nlog/nlog/wiki/Configuration-file for information on customizing logging rules and outputs. --> <!-- all targets in this section will automatically be asynchronous --> <targets async="true"> <!-- add your targets here See https://github.com/nlog/NLog/wiki/Targets for possible targets. See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers. --> <!-- Write events to a file with the date in the filename. <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} ${uppercase:${level}} ${message}" /> --> <target xsi:type="AsyncWrapper" name="MyLogger"> <target xsi:type="File" layout="${longdate} ${uppercase:${level}} ${message}" fileName="${basedir}/Log/${level}/${year}/${year_month}/${shortdate}.log" encoding="utf-8" /> </target> </targets> <rules> <!-- add your logging rules here --> <logger name="*" minlevel="Trace" maxlevel="Fatal" writeTo="MyLogger" /> <!-- Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f" <logger name="*" minlevel="Debug" writeTo="f" /> --> </rules> </nlog>
注意這裏的 nlog.config 配置想比較與log4net.config就簡單許多,且經過wapper的方式就能夠支持異步寫入文件,注意這裏須要自定義 variable 來達到以年份、月份創建對應文件夾存儲日期命名的日誌文件,由於這裏 nlog 自己木有提供 ${year} 這種相似參數,因此須要自定義配置使用,還好 nlog 考慮到了這方面的靈活性,效果圖參考以下:和log4net效果一致.....且對應日誌等級的文件寫入對應的等級文件夾中,至於更多的配置參考官方或者github wiki 吧
安全
雖然這兩個日誌框架,我相信大多人都在使用且也知道一些組織結構或者調用API等等,因此博主這裏算是「翻舊帳」的行爲了,主要是仍是對常規日誌文件存儲的一個備份配置的小文章,途中也查詢了相關資料,其實還有不少例如 layout 以及 header + footer 的消息美化,亦或者實現數據庫,nosql存儲日誌等等,都看各自的需求,固然咱們在使用日誌組件的時候確定是集成在系統中去使用的,那麼什麼時候咱們用靜態工具類LogHelper的方式仍是ILog接口注入的方式吶,相信你們都有各自的理解視狀況而定的吧......多線程