亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

詳解Spring Boot下使用logback 記錄多個文件日志

2019-11-26 09:42:54
字體:
供稿:網(wǎng)友

背景

這兩天遇到一個比較有意思的日志問題.

近期對我之前的python代碼進(jìn)行java的重構(gòu), 一方面是因為java使用的醫(yī)療庫非常健全穩(wěn)定, 可以商用. 另一方面是因為java速度快, 這個庫的實現(xiàn)的效率也高, 性能是Python版本的好幾倍.

但是作為這個項目的唯一作者, 我的癖好也成為這個項目的風(fēng)格. 這個項目會給很多部署工程師使用. 當(dāng)然項目的可用性和性能作為第一考慮的因素, 但是作為一個懶人, 對使用軟件時候的復(fù)雜部署過程和混亂調(diào)試信息深惡痛絕. 所以我在項目中使用了高度可配置/易用和多文件日志.

說道多文件日志, 它的優(yōu)點是每個日志只容納自身的邏輯, 所以對于一般的入門開發(fā)者或者是初級運維工程師查看起來非常方便.

初步嘗試

因為spring boot的配置一般來講是application.properties, 但是同時開發(fā)者可以使用yml格式的配置, 二者相比, yml文件更為簡潔. 熟讀python之禪的我當(dāng)然是簡潔勝于冗余選擇了yml.

發(fā)現(xiàn)spring-boot可以通過application.yml配置日志. 高興的配置一番之后發(fā)現(xiàn)沒法配置多個logger, 棄用! 改用logback-spring.xml(為什么不用logback.xml? 因為-spring這種文件可以獲取到spring配置中的變量.下面再說)

第一次實現(xiàn)

我有好幾個服務(wù)需要打日志. 一般來講我的日志風(fēng)格是 *.log 保存 INFO以上級別日志. *.err.log保存ERROR以上級別日志. 我如果每個文件日志都使用一個Appender的話, 配置文件太長了. 而且很難看, 不是我的風(fēng)格.

Google了一下, 發(fā)現(xiàn)了這種方案:

<?xml version="1.0" encoding="UTF-8"?><configuration>  # 下面這一行的意思是使用application.yml中的global.log-dir變量  <springProperty scope="context" name="LOG_DIR" source="global.log-dir" defaultValue="./log/"/>  <!-- 追加器開始 -->  # 這個是一個可以定義變量的Appender  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">    # 使用 LoggerNameBasedDiscriminator 這個類根據(jù)當(dāng)前Logger獲取變量    <discriminator class="com.utils.loggers.LoggerNameBasedDiscriminator">      <defaultValue>general</defaultValue>    </discriminator>    <sift>      # 根據(jù)變量loggerName名字生成根據(jù)日期滾動的Appender      <appender name="FILE-${loggerName}" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>          ${LOG_DIR}/${loggerName}.log        </file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">          <fileNamePattern>            ${LOG_DIR}/${loggerName}.%d{yyyy-MM-dd}.log.gz          </fileNamePattern>          <maxHistory>15</maxHistory>        </rollingPolicy>        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">          <level>INFO</level>        </filter>        <encoder>          <pattern>%d{HH:mm:ss.SSS} %-5level - %msg%n          </pattern>        </encoder>      </appender>      <appender name="FILE-ERROR-${loggerName}" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>${LOG_DIR}/${loggerName}.err.log</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">          <fileNamePattern>            ${LOG_DIR}/${loggerName}.%d{yyyy-MM-dd}.err.log.gz          </fileNamePattern>          <maxHistory>15</maxHistory>        </rollingPolicy>        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">          <level>ERROR</level>        </filter>        <encoder>          <pattern>%d{HH:mm:ss.SSS} %-5level - %msg%n          </pattern>        </encoder>      </appender>    </sift>  </appender>  <!-- 追加器結(jié)束 -->  <!-- 日志開始 -->  <logger name="com.some.service" level="INFO" additivity="false">    <appender-ref ref="SIFT"/>  </logger>  <!-- 日志結(jié)束 --></configuration>

下的是對應(yīng)的 LoggerNameBasedDiscriminator 類

package com.utils.loggers;import ch.qos.logback.classic.spi.ILoggingEvent;import ch.qos.logback.core.sift.AbstractDiscriminator;public class LoggerNameBasedDiscriminator extends AbstractDiscriminator<ILoggingEvent> {  private static final String KEY = "loggerName";  private String defaultValue;  public String getDefaultValue() {    return defaultValue;  }  public void setDefaultValue(String defaultValue) {    this.defaultValue = defaultValue;  }  # 這就是之所以xml里面可以引用loggerName變量的原因  public String getKey() {    return KEY;  }  public void setKey() {    throw new UnsupportedOperationException("Key not settable. Using " + KEY);  }  public String getDiscriminatingValue(ILoggingEvent e) {    String loggerName = e.getLoggerName();    if (loggerName == null)      return defaultValue;    else {      String[] split = loggerName.split("http://.");      return split[split.length - 1];    }  }}

最開始我的日志里面沒有報錯信息, 正常的生成INFO日志. 但是后來發(fā)現(xiàn)事情好像不是想象的那樣

問題出現(xiàn)

后來我把程序改成多線程. 發(fā)現(xiàn)所有涉及到多線程的服務(wù)日志里面都沒信息了. Google半天, 發(fā)現(xiàn)幾個令我震驚的真相:

  • 真相1: 所有滾動Appender都不支持異步追加 (其實也不是, 但是那種方式需要寫死日志文件名, 不推薦, 不講)
  • 真相2: SiftingAppender 內(nèi)部最多嵌套一個Appender. 所以理論上我的ERROR的日志里面應(yīng)該永遠(yuǎn)不會有內(nèi)容.

問題解決

對于之前的兩個問題, 分而治之.

不支持異步

再次谷歌(到這里讀者基本上發(fā)現(xiàn)了我搬磚的本質(zhì)), 發(fā)現(xiàn)有個Appender名字叫AsyncAppender, 這玩意是一個其他Appender的Wrapper. 說白了, 就是你打日志的命令是異步的, 放到隊列里面, 而它真正的打日志的動作是一個單獨的同步線程. 這就牛逼了, 使用這玩意收集我所有日志, 然后再轉(zhuǎn)發(fā)給SiftingAppender 進(jìn)行分發(fā)即可.

SiftingAppender 內(nèi)部最多嵌套一個Appender

這個好辦, 把INFO的Appender和ERROR的Appender拆開放到兩個SiftingAppender里面就行了, 不過這樣的話, 前面提到的的AsyncAppender 也要寫兩個.

最后, logback-spring.xml文件如下

<?xml version="1.0" encoding="UTF-8"?><configuration>  <springProperty scope="context" name="LOG_DIR" source="global.log-dir" defaultValue="./log/"/>  <!-- 追加器開始 -->  <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">    <discriminator class="com.utils.loggers.LoggerNameBasedDiscriminator">    </discriminator>    <sift>      <appender name="FILE-${loggerName}"           class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>${LOG_DIR}/${loggerName}.log</file>        <rollingPolicy            class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">          <fileNamePattern>            ${LOG_DIR}/${loggerName}.%d{yyyy-MM-dd}.log          </fileNamePattern>          <maxHistory>15</maxHistory>        </rollingPolicy>        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">          <level>INFO</level>        </filter>        <encoder>          <pattern>%d{HH:mm:ss.SSS} %-5level - %msg%n          </pattern>        </encoder>      </appender>    </sift>  </appender>  <appender name="SIFT-ERR" class="ch.qos.logback.classic.sift.SiftingAppender">    <discriminator class="com.infervision.utils.loggers.LoggerNameBasedDiscriminator">    </discriminator>    <sift>      <appender name="FILE-ERROR-${loggerName}" class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>${LOG_DIR}/${loggerName}.err.log</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">          <fileNamePattern>            ${LOG_DIR}/${loggerName}.%d{yyyy-MM-dd}.err.log          </fileNamePattern>          <maxHistory>15</maxHistory>          <totalSizeCap>50MB</totalSizeCap>        </rollingPolicy>        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">          <level>ERROR</level>        </filter>        <encoder>          <pattern>%d{HH:mm:ss.SSS} %-5level - %msg%n          </pattern>        </encoder>      </appender>    </sift>  </appender>  <!-- 異步輸出 -->  <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">    <!-- 不丟失日志.默認(rèn)的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 -->    <discardingThreshold >0</discardingThreshold>    <!-- 更改默認(rèn)的隊列的深度,該值會影響性能.默認(rèn)值為256 -->    <queueSize>512</queueSize>    <!-- 添加附加的appender,最多只能添加一個 -->    <appender-ref ref ="SIFT"/>  </appender>  <!-- 異步輸出 -->  <appender name ="ASYNC-ERR" class= "ch.qos.logback.classic.AsyncAppender">    <!-- 不丟失日志.默認(rèn)的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 -->    <discardingThreshold >0</discardingThreshold>    <!-- 更改默認(rèn)的隊列的深度,該值會影響性能.默認(rèn)值為256 -->    <queueSize>512</queueSize>    <!-- 添加附加的appender,最多只能添加一個 -->    <appender-ref ref ="SIFT-ERR"/>  </appender>  <!-- 追加器結(jié)束 -->  <!-- 日志開始 -->  <logger name="com.some.service" level="INFO" additivity="false">    <appender-ref ref="ASYNC"/>  </logger>  <!-- 日志結(jié)束 --></configuration>

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
中文官网资源新版中文第二页在线观看| 99在线免费视频观看| 日本桃色视频| 黄页网站一区| 麻豆一区二区| 欧美日韩福利| 亚洲综合图片一区| 潮喷失禁大喷水aⅴ无码| 在线免费观看一区二区| 日本丰满少妇黄大片在线观看| 色悠悠在线视频| 51vv免费精品视频一区二区| 丝袜人妻一区二区三区| 国产一区欧美日韩| 亚洲在线观看视频网站| 国产小视频在线播放| 91嫩草国产在线观看| 日韩电影第一页| 亚洲综合激情小说| 日韩精品久久久久久免费| 精品一区二区三区免费毛片爱| 大香煮伊手机一区| 99理论电影网| 久久久亚洲影院你懂的| 先锋影音一区二区| 成年网站在线在免费播放| 国产精品国产三级国产普通话对白| 啪啪国产精品| 欧美日韩性生活视频| 97在线精品国自产拍中文| 91成人免费| 欧美videosex性极品hd| 亚洲日本va中文字幕久久| 免费成人在线视频观看| 一区二区三区自拍| 自己做鸭怎么接单寻找客源| 欧美日韩国产天堂| 欧美中文字幕一区二区| 337p日本欧洲亚洲大胆精品| 5g影院5g天天爽永久免费影院| 日本免费一区二区三区视频观看| 五月天视频一区| 久9re热视频这里只有精品| 少妇人妻丰满做爰xxx| 日韩电影在线观看中文字幕| 精品一区二区三区在线观看视频| 亚洲精品第一国产综合野| 成人1区2区3区| 国产日韩一区二区在线| 久久久久国产精品一区二区| 国产伦精品一区二区三区四区免费| heyzo高清中文字幕在线| 国产一区二区三区四区福利| 青青草手机在线观看| 精品久久国产精品| 国产精品1234区| 久久亚洲国产精品日日av夜夜| 无套白嫩进入乌克兰美女| 国产精品igao| 最近中文字幕在线中文高清版| 中文字幕剧情在线观看一区| 无码少妇精品一区二区免费动态| 欧美激情一区二区三区久久久| 极品裸体白嫩激情啪啪国产精品| 日本一区午夜艳熟免费| 国产精品毛片a∨一区二区三区|国| 91免费看网站| 亚洲高清免费观看| 澳门成人av| 亚洲蜜桃视频| 91在线观看免费观看| 亚洲欧美日韩一区成人| 同产精品九九九| 欧美日韩激情美女| 国内精品自线一区二区三区视频| 亚洲精品18p| 小早川怜子一区二区的演员表| 小处雏高清一区二区三区| 欧美综合自拍| 奇米影视在线99精品| 精品国产一区二区三区麻豆免费观看完整版| 在线免费国产视频| 美女网站视频黄色| 91精品久久久久久久久久入口| 国产传媒视频在线| 国产精品成久久久久| av白虎一区| 免费观看a视频| 成人免费看黄网址| 美日韩一区二区三区| 日本欧美黄网站| 国产卡一卡二在线| 麻豆传媒在线播放| 亚洲成人黄色小说| 国产视频123区| 91丨九色丨国产| 狠狠狠综合7777久夜色撩人| 欧美日韩不卡| 盗摄系列偷拍视频精品tp| 日本一二区视频| 丰满人妻一区二区三区免费| 四虎www4hu永久免费| 亚洲 欧美 日韩 综合| xnxx国产精品| 国产精品91在线观看| 91香蕉亚洲精品| 捆绑紧缚一区二区三区视频| 久久全国免费久久青青小草| 亚洲色成人www永久在线观看| 国产精品美女久久久久久久久久久| 微拍福利一区二区| 日韩欧美一区二区三区在线视频| 国产一国产二国产三| 欧美国产日韩一区二区| 狠狠人妻久久久久久| h色视频在线观看| 国产精品v欧美精品v日本精品动漫| 亚洲男人第一av| 亚洲白虎美女被爆操| 视频二区在线观看| 91手机在线播放| 中文字幕中文字幕在线中文字幕三区| 不卡视频免费在线观看| 99re8在线精品视频免费播放| 日韩专区在线| 国产女人18毛片水18精| 精品久久久久久久久久久久| 国产麻豆91视频| 国产高清视频一区三区| 成人乱码手机视频| 成人全视频在线观看在线播放高清| 唐人社导航福利精品| 7777久久亚洲中文字幕| 日本一区二区三区精品视频| av免费观看大全| 1024成人网色www| 天堂地址在线www| 性色av无码久久一区二区三区| 91免费版在线看| 亚洲色图第四色| 日韩成人一区| 91成人午夜| 国产视频福利一区| 动漫h在线观看| 亚洲国产高清自拍| 精品一区二区三区高清免费不卡| 无码人妻精品一区二区三| 手机在线国产视频| 欧美日韩人妻精品一区在线| 国产一级黄色| 成人在线手机视频| 久久久久99精品成人片试看| 国产精品久久久久婷婷| 国产成人综合在线观看| 一级片免费在线观看| 国产成人tv| 久草中文综合在线| 日本免费观看网站| 欧美久久久久久久久中文字幕| 国产精品videossex久久发布| 成人av免费在线播放| 精品日本12videosex| 久久久精品美女| 国产精品欧美一区二区三区奶水| 日韩av免费在线播放| 草草视频在线免费观看| 一区二区三区一级片| 欧美大香线蕉线伊人久久| 久久久亚洲福利精品午夜| 久久―日本道色综合久久| 毛片基地黄久久久久久天堂| 免费在线黄网站| 日韩专区在线| 国产一区二区三区小说| 久久av资源网站| 亚洲国产色一区| 日韩欧美国产三级| 精品视频二区三区| 91香蕉视频污在线观看| 久久婷婷国产综合尤物精品| 国产性猛交普通话对白| 国产成a人亚洲精v品无码| 国产日本在线视频| 精品亚洲一区二区三区四区五区高| 亚洲精品综合在线观看| 欧美亚洲国产日本| 久久久久国产精品午夜一区| 国产99久久九九精品无码| 成熟丰满熟妇高潮xxxxx视频| 亚洲国产日产av| 伊人激情综合网| 国产激情美女久久久久久吹潮| 91精品国产乱码久久蜜臀| 欧美激情亚洲另类| 毛片网站大全| 国产三级精品三级在线观看| 欧美男同视频网| 国产精品毛片久久久久久| www.老鸭窝.com| 成人午夜视频在线观看| 91热视频在线观看| 米奇.777.com| 久久无码人妻一区二区三区| 色婷婷国产精品久久包臀| 92裸体在线视频网站| 欧美孕妇孕交xxⅹ孕妇交| www成人在线观看| 亚洲乱码国产乱码精品精98午夜| 亚洲欧美韩国| 亚洲中文字幕无码av| 综合伊思人在钱三区| 色婷婷视频在线| av资源种子在线观看| 国产免费av在线| 成人福利视频在| 伊人久久影院| 欧美精品少妇videofree| 亚洲女人视频| 色先锋av资源| 精品久久久久久中文字幕人妻最新| 2023亚洲男人天堂| 欧美黑人做爰爽爽爽| 午夜视黄欧洲亚洲| 欧美日韩国产黄| 欧美一区二区精品在线| 久久精品.com| wwwav在线| 久久久精品少妇| 精品久久久久一区二区国产| 免费看黄在线看| 最近最好的中文字幕2019免费| 激情久久久久久| 国产高清一区二区三区| 性欧美videos高清hd4k| 午夜精品一区二区三级视频| 日本一二三不卡视频| 玖草视频在线| 久热这里只有精品6| 人人九九精品| 国产精品一区二区三区四区| 精品成人乱色一区二区| 亚洲视频导航| 国产一区二区女| 国产一区二区视频网站| 蜜臀视频在线观看| 亚洲一区在线直播| 精品盗摄女厕tp美女嘘嘘| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲最大综合网| 日韩欧美国产精品| 首页亚洲欧美制服丝腿| 鲁片一区二区三区| 亚洲国产精彩视频| 婷婷成人综合网| 成人免费看黄网站| 国产v综合v亚洲欧美久久| 色老板亚洲精品一区| 午夜国产精品视频免费体验区| 亚洲xxxx18| 国产精品高潮在线| 亚洲黄色成人| 精品视频一区二区在线| 91污色多多| 91成年人网站| 婷婷六月激情| 欧美精品第三页| 日本a在线天堂| 久久久国产综合精品女国产盗摄| 91久久久亚洲精品| 美女一区二区视频| 成人xxxx| 国产精品51麻豆cm传媒| 在线看片不卡| 国产一区二区三区日韩| 日韩国产欧美三级| 亚洲白虎美女被爆操| 亚洲欧美精品久久| 久久99青青精品免费观看| 欧美日韩国产色| 男人捅女人免费视频| 精品国产免费人成网站| 久久不射电影网| 久久久精彩视频| 秋霞午夜理伦电影在线观看| 亚洲人高潮女人毛茸茸| 在线日韩av观看| 日本18中文字幕| 精品少妇一区二区三区| 成人精品国产免费网站| 黄页视频在线播放| 久久久久久久久久久久久91| 欧美精品乱码久久久久久| 欧洲美女亚洲激情| 国产一级一片免费播放放a| 国内自拍视频在线播放| 九九热视频免费在线观看| 亚洲精品黄网在线观看| av文字幕在线观看| 久草青青在线观看| 国产精品一国产精品| 好吊妞国产欧美日韩免费观看网站| 菠萝蜜视频网址| aⅴ色国产欧美| 欧美成人精品| 国产精品自拍网站| 在线国产亚洲欧美| 综合天堂久久久久久久| 中文字幕在线观看你懂的| 亚洲黄色小说视频| 999久久久亚洲| 国产精品第一第二| 五月激情六月婷婷| 欧美性xxxx巨大黑人猛| 国产精品美女网站| 99riav国产精品视频| 色偷偷88888欧美精品久久久| 欧美r片在线| 欧美aaaaaa| 凹凸成人精品亚洲精品密奴| 久久久久久久亚洲| 特级西西人体高清大胆| 免费观看成人在线| 三级网站在线免费观看| 99re在线| 国产精品热视频| 一区二区三区视频在线免费观看| 亚洲免费伊人电影在线观看av| 色999韩欧美国产综合俺来也|