<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          不正經(jīng)人愛寫日志

          共 4568字,需瀏覽 10分鐘

           ·

          2021-11-04 11:42

          第零篇簡(jiǎn)單介紹了austin項(xiàng)目做什么用的,這兩個(gè)月我重點(diǎn)會(huì)實(shí)現(xiàn)哪一塊內(nèi)容。

          第一篇用Maven+SpringBoot搭好了項(xiàng)目的架子,以及聊了下我對(duì)SpringBoot和Maven的看法。

          總的來說,我感覺這次的反響是不錯(cuò)的,雖然閱讀量不高。但留言的人多了很多,也有很多人都擔(dān)心我會(huì)不會(huì)鴿掉(更新一半中途就斷了)

          我只能說:別慌,絕對(duì)不鴿,你只管追更就好。

          我已經(jīng)決定每個(gè)周末都扛著電腦回家,有空就往附近的圖書館里跑(圖書館是學(xué)習(xí)的YYDS,在家的效率就是要比圖書館要低不少)

          不多BB了,今天繼續(xù)聊個(gè)話題:日志

          01、什么是日志

          所謂日志,在我理解下就是:記錄程序運(yùn)行時(shí)的信息

          在Java最初期又或是我們初學(xué)階段,打印日志全憑System.out.println();

          這好用嗎?有待商榷。

          對(duì)于大部分初學(xué)者來說,好用!我想看的信息,直接在console就能看到了,這是多么地方便阿。學(xué)習(xí)Java的第一個(gè)運(yùn)行結(jié)果都是由System.out.println();出來的,不需要有任何的學(xué)習(xí)成本。

          對(duì)于大部分工作者來說,本地調(diào)試可以,但如果程序部署到服務(wù)器以后,那就算了。

          生產(chǎn)環(huán)境跟本地環(huán)境是有區(qū)別的:

          • 生產(chǎn)環(huán)境需要記錄的日志會(huì)更多(畢竟是作為一個(gè)系統(tǒng)/項(xiàng)目在線上運(yùn)行,不可能只打印一點(diǎn)點(diǎn)內(nèi)容)
          • 生產(chǎn)環(huán)境的日志內(nèi)容需要保留至文件(作為留存,線上不會(huì)說第一時(shí)間發(fā)現(xiàn)問題,很多需要查找歷史日志數(shù)據(jù))
          • 生產(chǎn)環(huán)境的日志內(nèi)容需要有一定的規(guī)范格式(至少日志記錄的時(shí)間需要有吧)
          • ...

          上面這些要求,System.out.println();都是不具備的。

          所以,我們可以看到在公司里寫的項(xiàng)目,是沒有用System.out.println();記錄日志的

          02、Java日志體系

          工作了以后,你會(huì)發(fā)現(xiàn)每次引入一個(gè)框架,這個(gè)框架下幾乎都有對(duì)應(yīng)的日志包。

          我之前在公司里曾經(jīng)整合過幾個(gè)項(xiàng)目(將原有的幾個(gè)工程合并到一個(gè)項(xiàng)目?jī)?nèi))。

          系統(tǒng)分久必合合久必分,當(dāng)時(shí)是認(rèn)為以前的同事把項(xiàng)目拆得過于細(xì),造成一定的資源浪費(fèi)(畢竟每個(gè)工程跑在線上至少都會(huì)部署兩臺(tái)線上機(jī)器),所以有段時(shí)間公司就希望我們把一些細(xì)小的項(xiàng)目進(jìn)行合并。

          至于這做得對(duì)與錯(cuò),這塊我就不談了。

          在合并的過程中,最最最麻煩的就是解決依賴沖突的問題(都是Maven項(xiàng)目,會(huì)有Maven仲裁的問題),而這里邊,最明顯的就是Java日志包的問題。

          如果你有那么一丟丟了解Java日志,你就應(yīng)該多多少少聽說過以下的名字:Log4j(log for java)、JUL(Java Util Logging)、JCL(Jakarta Commons Logging)、Slf4j(Simple Logging Facade for Java)、Logback、Log4j2

          如果你比較細(xì)心,你會(huì)發(fā)現(xiàn),不同的技術(shù)框架所采用的Java日志實(shí)現(xiàn)都很有可能不一樣的。

          既然實(shí)現(xiàn)不一樣,那對(duì)應(yīng)的API調(diào)用是不是就不一樣?(畢竟它還不像是JDBC,定義了一套接口規(guī)范,各個(gè)數(shù)據(jù)庫廠商去實(shí)現(xiàn)JDBC規(guī)范,程序員面向JDBC接口編程就完事了)

          那這這這不是亂套呢?想到這里,血壓就逐漸就上來了?這別慌,上面提到的Java日志Slf4j(Simple Logging Facade for Java)干的就類似JDBC做的事情。

          它定義了日志的接口(門面模式),當(dāng)項(xiàng)目使用別的日志框架時(shí),那就適配它?。ㄗ⒁猓篔DBC是定義接口,數(shù)據(jù)庫廠商實(shí)現(xiàn)。Slf4j也定義了接口,但是它適配其他的Java日志實(shí)現(xiàn),騷不騷?)

          我們看Slf4j官網(wǎng)的一張圖,應(yīng)該就挺好理解了:

          扯了這么久,我想表達(dá)的是:我們?cè)陧?xiàng)目中,最好是使用Slf4j提供的API,至于真實(shí)的LOG實(shí)現(xiàn),都可以用Slf4j進(jìn)行橋接(這樣一來,或許將來有一天說要從log4j改為logback,那程序代碼也不用改動(dòng))

          03、日志有什么用?

          還沒有過生產(chǎn)環(huán)境的開發(fā)的同學(xué)可能認(rèn)為記錄日志就是用來定位問題的,其實(shí)并不完全是。

          日志一方面我們用它來定位問題,一方面我們很多的數(shù)據(jù)也是來源于日志

          不要覺得存在數(shù)據(jù)庫里的數(shù)據(jù)才是重要的,我們程序運(yùn)行時(shí)記錄下的日志數(shù)據(jù)也同樣重要

          在大數(shù)據(jù)領(lǐng)域里,數(shù)據(jù)來源有很多:關(guān)系型數(shù)據(jù)庫、爬蟲、日志等等

          舉個(gè)例子,我以前的公司就有處理日志的一套框架:

          1. 我們正常把日志信息輸出到文件下
          2. 框架提供后臺(tái)給予我們配置(文件的路徑以及Kafka Topic Name)

          該框架做的事情說白了就是:把我們的日志文件內(nèi)容轉(zhuǎn)成Kafka消息(如果使用方需要將哪個(gè)日志文件的內(nèi)容轉(zhuǎn)為MQ消息,那在平臺(tái)上配置下就完事了)

          有了Kafka消息,那配合流式處理平臺(tái)(Storm/Spark/Flink)再對(duì)日志進(jìn)行清洗,是不是就能產(chǎn)生有價(jià)值的數(shù)據(jù)

          04、Austin 日志

          扯了這么久的日志基礎(chǔ),只是想讓還不了解日志的同學(xué)有個(gè)認(rèn)知。

          不扯別的了,還是回到我們還在「新建文件夾」階段的austin項(xiàng)目吧。

          austin項(xiàng)目的搭建技術(shù)框架使用的是SpringBoot,SpringBoot默認(rèn)的日志組合是:Slf4j + logback

          我在公司接觸到的項(xiàng)目幾乎都是這個(gè)組合,所以我就不打算動(dòng)了,就直接用logback作為austin的日志實(shí)現(xiàn)框架了(要是真有那么一天要改成別的日志實(shí)現(xiàn),理論上只要引入對(duì)應(yīng)的橋接包就完事了)。

          05、logback日志初體驗(yàn)

          在無任何配置的前提下,只要我們引入了SpringBoot的包,就能直接使用日志的功能了。具體效果入下圖

          SpringBoot是約定大于配置的一個(gè)框架

          SpringBoot會(huì)默認(rèn)去加載resources下名為logback.xml 或者 logback-spring.xml的配置文件( xml 格式也可以改為 groovy 格式)

          如果都不存在,那么 logback 默認(rèn)地會(huì)調(diào)用BasicConfigurator ,創(chuàng)建一個(gè)最小化配置。

          最小化配置由一個(gè)關(guān)聯(lián)到根 logger 的ConsoleAppender 組成。輸出用模式為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n?的 PatternLayoutEncoder 進(jìn)行格式化

          06、logback配置

          從上面可以發(fā)現(xiàn)的是,默認(rèn)的logback配置是不符合我們的要求的(它是打印在console的),我們是希望把日志記錄在文件下的。

          所以,我們會(huì)在resources下新建一個(gè)logback配置。常見的配置內(nèi)容如下:



          <configuration?scan="true"?scanPeriod="10?seconds">

          ????<contextName>austincontextName>

          ????
          ????<property?name="log.path"?value="logs"/>


          ????<appender?name="CONSOLE"?class="ch.qos.logback.core.ConsoleAppender">
          ????????<encoder?class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
          ????????????
          ????????????<pattern>%d{yyyy-MM-dd?HH:mm:ss.SSS}?[%thread]?%-5level?%logger{50}?-?%msg%npattern>
          ????????????
          ????????????<charset>UTF-8charset>
          ????????encoder>
          ????appender>


          ????
          ????<appender?name="INFO_FILE"?class="ch.qos.logback.core.rolling.RollingFileAppender">
          ????????
          ????????<file>${log.path}/austin-info.logfile>
          ????????
          ????????<encoder>
          ????????????<pattern>%d{yyyy-MM-dd?HH:mm:ss.SSS}?[%thread]?%-5level?%logger{50}?-?%msg%npattern>
          ????????????<charset>UTF-8charset>
          ????????encoder>
          ????????
          ????????<rollingPolicy?class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          ????????????
          ????????????<fileNamePattern>${log.path}/logs/austin-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
          ????????????<timeBasedFileNamingAndTriggeringPolicy?class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
          ????????????????<maxFileSize>1000MBmaxFileSize>
          ????????????timeBasedFileNamingAndTriggeringPolicy>
          ????????????
          ????????????<maxHistory>15maxHistory>
          ????????rollingPolicy>
          ????????
          ????????<filter?class="ch.qos.logback.classic.filter.LevelFilter">
          ????????????<level>infolevel>
          ????????????<onMatch>ACCEPTonMatch>
          ????????????<onMismatch>DENYonMismatch>
          ????????filter>
          ????appender>

          ????
          ????<appender?name="ERROR_FILE"?class="ch.qos.logback.core.rolling.RollingFileAppender">
          ????????
          ????????<file>${log.path}/austin-error.logfile>
          ????????
          ????????<encoder>
          ????????????<pattern>%d{yyyy-MM-dd?HH:mm:ss.SSS}?[%thread]?%-5level?%logger{50}?-?%msg%npattern>
          ????????????<charset>UTF-8charset>?
          ????????encoder>
          ????????
          ????????<rollingPolicy?class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          ????????????<fileNamePattern>${log.path}/austin-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
          ????????????<timeBasedFileNamingAndTriggeringPolicy?class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
          ????????????????<maxFileSize>1000MBmaxFileSize>
          ????????????timeBasedFileNamingAndTriggeringPolicy>
          ????????????
          ????????????<maxHistory>15maxHistory>
          ????????rollingPolicy>
          ????????
          ????????<filter?class="ch.qos.logback.classic.filter.LevelFilter">
          ????????????<level>ERRORlevel>
          ????????????<onMatch>ACCEPTonMatch>
          ????????????<onMismatch>DENYonMismatch>
          ????????filter>
          ????appender>

          ????<root?level="info">
          ????????
          ????????<appender-ref?ref="CONSOLE"/>
          ????????<appender-ref?ref="INFO_FILE"/>
          ????????<appender-ref?ref="ERROR_FILE"/>
          ????root>

          configuration>

          日志的配置不會(huì)是一成不變的,現(xiàn)在項(xiàng)目剛搭建出來,就怎么簡(jiǎn)單怎么來。

          07、彩蛋

          這篇文章發(fā)布的前一個(gè)晚上,ZhenDong突然問我現(xiàn)在用的什么MQ比較多,我隨口一答:Kafka吧,我接觸MQ基本都是Kafka

          他說在寫一個(gè)好東西,到時(shí)候發(fā)出來。我這一聽,就肯定感興趣了啊。

          ZhenDong發(fā)的文章鏈接:https://mp.weixin.qq.com/s/JC51S_bI02npm4CE5NEEow

          文章大概就是美團(tuán)大佬們他們用AOP+動(dòng)態(tài)模板封裝了一套SDK,進(jìn)而優(yōu)雅地記錄操作日志(說人話就是:大佬不想日志寫在業(yè)務(wù)代碼上,難以管理。將寫日志這個(gè)動(dòng)作抽象出來,用注解來統(tǒng)一記錄日志)

          文章還是很精彩的,我推薦閱讀一遍。

          ZhenDong大佬看完文章后,自己實(shí)現(xiàn)了一套,已經(jīng)差不多快要完成了。順便我跟他討論了下使用場(chǎng)景,感覺我的項(xiàng)目也可以用那一套東西(有優(yōu)雅的打日志方式,誰不愛呢

          我已經(jīng)預(yù)定了,到時(shí)候他給我發(fā)源碼,我就學(xué)習(xí)下實(shí)現(xiàn)思路(后面項(xiàng)目也用他提供的SDK來打日志,有問題就開噴??[狗頭.jpg])。等他忙完寫好文章,我也轉(zhuǎn)載下跟大家一起學(xué)習(xí)下。

          像這種輪子或者說是經(jīng)驗(yàn)思路,自己學(xué)會(huì)了以后,就可以在面試的時(shí)候吹了。就說自己對(duì)項(xiàng)目系統(tǒng)改造了一把,從原來的破鬼樣(介紹背景),變成現(xiàn)在如此優(yōu)雅(得到的結(jié)果),并這個(gè)過程中穿插自己的實(shí)現(xiàn)思路以及遇到的坑(艱辛的過程),這種亮點(diǎn)哪個(gè)面試官又不愛呢

          08、總結(jié)

          日志在一個(gè)項(xiàng)目里,我認(rèn)為是在一個(gè)比較重要的位置上的。我們的數(shù)據(jù)和定位問題都離不開日志,有的項(xiàng)目的日志相當(dāng)混亂,那維護(hù)起來就特別特別麻煩。

          其實(shí)我完全可以自己寫個(gè)logback配置就把這塊給忽略了,但我還是堅(jiān)持梳理出來,這篇文章按照「項(xiàng)目」的維度從頭梳理了一遍日志的知識(shí),希望對(duì)大家有幫助吧。

          另外,《對(duì)線面試官》公眾號(hào)還在持續(xù)分享面試題,沒關(guān)注的同學(xué)可以關(guān)注一波(近期我想把文字版上傳上去了)

          瀏覽 42
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级黄色毛片播放 | 男女抽插视频 | 激情亚洲网站 | www.91蝌蚪 | 成人18禁免费网站 |