摘要:背景大量項(xiàng)目在使用記日志,有部分項(xiàng)目使用日志混亂,格式不統(tǒng)一,多數(shù)人搞不懂配置文件,導(dǎo)致配置錯(cuò)誤,現(xiàn)在需要開發(fā)一套統(tǒng)一的少配置的日志組件,使用方便。
背景
大量項(xiàng)目在使用logback記日志,有部分項(xiàng)目使用日志混亂,格式不統(tǒng)一,多數(shù)人搞不懂配置文件,導(dǎo)致配置錯(cuò)誤,現(xiàn)在需要開發(fā)一套統(tǒng)一的、少配置的日志組件,使用方便。
設(shè)計(jì)思路盡量采用0配置,無logback.xml
日志格式統(tǒng)一,方便后續(xù)日志分析系統(tǒng)
只有兩個(gè)日志級(jí)別,一個(gè)是正常日志,一個(gè)是異常日志
提供log4j、jcl、logback、commons-log等橋接方案及版本兼容方案
提子線程、json格式化輸出、map格式化、數(shù)組格式化、請(qǐng)求響應(yīng)參數(shù)(供耗時(shí))等便捷日志輸出方法
支持redis、db、http自動(dòng)開關(guān)配置**
新增日志類型(logger)api采用流式結(jié)構(gòu),類似StringBuffer
概要設(shè)計(jì) 零配置調(diào)研代碼
java static LoggerContext lc; static { lc = (LoggerContext) LoggerFactory.getILoggerFactory(); // 對(duì)應(yīng)配置中的appender ConsoleAppender ca = new ConsoleAppender(); ca.setContext(lc); ca.setName("console"); // 格式 PatternLayoutEncoder pl = new PatternLayoutEncoder(); pl.setContext(lc); pl.setPattern("%d{MMddHHmmss.SSS} [%thread] %-5level %logger{36} - %msg%n"); pl.start(); ca.setEncoder(pl); ca.start(); // 對(duì)應(yīng)配置中的logger ch.qos.logback.classic.Logger rootLogger = lc.getLogger("com.test"); rootLogger.addAppender(ca);}
上面代碼等價(jià)于下面的xml
%d{MMddHHmmss.SSS} [%thread] %-5level %logger{36} - %msg%n
由此可以隨意把配置文件中的內(nèi)容以代碼形式編寫,理論已經(jīng)可以實(shí)現(xiàn)0配置。
輸出路徑約定固定將日志輸出到,相對(duì)路徑log/xxx.yyyy-MM-dd-HH.log,其中xxx為logger的name
日志格式格式固定:
MMddHHmmss.SSS||id||【交易名★子步驟】||context ||level
例:
150000.311||N-XrUTQzIc1531897200311||【CiTeeFilter★ci攔截器】||ci攔截器 請(qǐng)求的完整參數(shù)為:{"merchantId":["0012444"],"userId":["13112341232"]} ||INFO
固定格式的核心代碼,攔截到日志請(qǐng)求,按照格式拼裝,主要方法為繼承ThrowableProxyConverter和MessageConverter來實(shí)現(xiàn)對(duì)日志的攔截,并修改為想要的格式,其中使用的例如id等放到本地變量?jī)?nèi),核心是對(duì)MDC的使用
所有日志都默認(rèn)輸出到這里 logger name:service 系統(tǒng)初始化時(shí),定義這個(gè)Logger和appender,即這個(gè)Logger為root log
自定義的logger提供addLogger方法,參數(shù) packageName 包名,例如:com.test 必輸參數(shù) 如果name未設(shè)置時(shí),name默認(rèn)為包名最后一個(gè).后面的字符 name 名字,決定日志文件的名字 非必輸 path 日志路徑 非必輸 additivity 是否輸出到root log內(nèi)
特殊的log
提供特殊組件的log配置,例如: redis 默認(rèn)ERROR http 默認(rèn)ERROR db連接池 默認(rèn)ERROR kafka 默認(rèn)ERROR schedul 默認(rèn)ERROR spring 默認(rèn)ERROR
提供exception異常棧格式打印 提供帶換行的格式化打印 代碼思路:繼承ThrowableProxyConverter,獲取異常棧,在每行的前面插入固定格式文本
普通日志api(VirgoLog)方法 | 方法描述 |
---|---|
setUniqKey(id) | 設(shè)置當(dāng)前線程id,線程開始時(shí)設(shè)置即可,后面無需設(shè)置 |
updateStep(trade, step) | 更新當(dāng)前id的步驟信息 |
log(msg, param) | 記錄普通日志,msg替換規(guī)則,普通替換為{},如果想替換為業(yè)務(wù)日志api中的格式,使用``替換 |
logErr(msg, e) | 記錄異常日志 |
log( trade, step, msg, param) | 記錄普通日志,此方法會(huì)自動(dòng)更新id、trade、step,不建議使用 |
logErr(trade, step, msg, e) | 記錄異常日志 |
log(cid, trade, step, msg, param) | 記錄普通日志,此方法會(huì)自動(dòng)更新id、trade、step,不建議使用 |
logErr(cid, trade, step, msg, e) | 記錄異常日志 |
debug(msg, param) | 記錄debug級(jí)別日志,不建議使用 |
平時(shí)記日志時(shí),如果某個(gè)類沒有時(shí)間toString方法,會(huì)無法正確打印出數(shù)據(jù),此時(shí)提供替換方法,直接將object替換為json打印,核心代碼思路為
MessageFormatter是處理{}替換的類,重新寫個(gè)類,稍加改動(dòng)即支持{}也支持`` ,并判斷替換為json還是toString api如下
方法 | 方法描述 |
---|---|
begin(msg) | 記錄開始 |
end(msg) | 記錄完成,會(huì)打印本線程內(nèi)上一個(gè)begin到現(xiàn)在的耗時(shí) |
logJson(json, format) | 記錄json格式化日志,format表示是否換行 |
logMap(map, format) | 記錄map格式化日志 |
logCollection(list, format) | 記錄集合格式化日志 |
logArray(array, format) | 記錄數(shù)組格式化日志 |
logObjct(obj, format) | 記錄Object格式化日志 |
方法 | 方法描述 |
---|---|
getLogger() | 獲取logger,用于記日志 |
getLogger(name) | 通過name獲取logger |
addLogger() | 參考自定義Logger,如果logger已經(jīng)創(chuàng)建,則不再創(chuàng)建,一般不使用,除非想自定義日志名等 |
consoleOpen() | 打開控制臺(tái)日志,系統(tǒng)啟動(dòng)時(shí)默認(rèn)配置控制臺(tái)日志 |
commonOpen(name, level) | 默認(rèn)的組件都是error級(jí)別,這個(gè)方法可以變更日志級(jí)別,例如redis http等 |
map:即轉(zhuǎn)化為json,然后再格式化
collection:同上
array:也同上
object:同上
1、密碼脫敏、加解密有必要多帶帶提取方法嗎
2、提供父線程打印開關(guān)
maven依賴democom.cdc.ecliptic virgo 1.5_1.6-SNAPSHOT
public static void main(String[] args) throws InterruptedException { // 啟動(dòng) VirgoLancher.start("hahaha", "com.cdc.virgo", "D:/test/hahah.log"); LoggerHelper.commonOpen("hahaha", LogLevel.DEBUG); Logger logger1 = LoggerFactory.getLogger("druid"); // VirgoLancher.commonStart("abc", "com.cdc.virgo"); // 打開控制臺(tái) LoggerHelper.consoleOpen(); // 設(shè)置cid VirgoLog.setUniqKey(null); // 設(shè)置步驟名和交易名 VirgoLog.updateStep("adfa", "saf"); // 獲取Logger VirgoLog logger = VirgoLog.getLogger(); // 打開debug級(jí)別(只有在開發(fā)階段可以打開) // logger.changeLevel(LogLevel.DEBUG); // 記錄換行 logger.log("a"); logger1.info("ffffdffffdffffdd"); logger1.error("ffffdffffdffffdd"); // logger1.info("sfdasfaf" + // " afafdasfd" + // " asfdasf"); logger.log("sfdasfaf" + " afafdasfd" + " asfdasf"); // logger1.info("b"); // 正常日志 // logger.log("我只有一行"); Mapmap = new HashMap(); map.put("asdf", "1"); map.put("asdf2", "2"); map.put("asdf3", "13"); map.put("asdf4", "14"); map.put("asdf5", "15"); map.put("asdf6", "16"); // // 異常日志也支持格式化 // logger.logErr("我錯(cuò)了:{},你沒錯(cuò):~~", new Exception("asdfsaflk"), "啊", map); // logger.log("----------------------------------------------"); // // {}替換普通對(duì)象,調(diào)用toString() ~~把對(duì)象轉(zhuǎn)換為json并且格式化輸出 ``把對(duì)象轉(zhuǎn)換為json不格式化輸出 logger.log("你好{},你是誰~~``,sd~xx {}", map, map, map, "tttt"); VirgoLog.updateStep("saf2"); // // 把對(duì)象轉(zhuǎn)換為json輸出 // logger.logJson(map, false); // // 更新步驟名和交易名 // VirgoLog.updateStep("bbbbb", "ccccc"); // // 耗時(shí)日志打印 logger.begin("處理內(nèi)容"); logger.begin("處理第二個(gè)"); logger.begin("處理第三個(gè)"); Thread.sleep(3000L); logger.end(); Thread.sleep(1000L); logger.end(); VirgoLog.updateStep("saf3"); logger.end(); // // 記錄debug日志,一般調(diào)試用 // logger.logDebug("jajajajaja"); // List l = new ArrayList(); // B b = new B(); // try { // b.b(); // } catch (Exception e) { // logger.logErr("woqu", e); // } }
宜信技術(shù)學(xué)院
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/72861.html
摘要:容器化應(yīng)用日志收集挑戰(zhàn)應(yīng)用日志的收集分析和監(jiān)控是日常運(yùn)維工作重要的部分,妥善地處理應(yīng)用日志收集往往是應(yīng)用容器化重要的一個(gè)課題。日志來源識(shí)別采用統(tǒng)一應(yīng)用日志收集方案,日志分散在很多不同容器的相互隔離的環(huán)境中,需要解決日志的來源識(shí)別問題。 容器化應(yīng)用日志收集挑戰(zhàn) 應(yīng)用日志的收集、分析和監(jiān)控是日常運(yùn)維工作重要的部分,妥善地處理應(yīng)用日志收集往往是應(yīng)用容器化重要的一個(gè)課題。 Docker處理日志...
摘要:應(yīng)用的研發(fā)上線運(yùn)維運(yùn)營形成閉環(huán),順利完成從對(duì)內(nèi)服務(wù)到公共平臺(tái)的升級(jí)。從功能角度,只能支持靜態(tài)方式設(shè)置反向代理,然后,而平臺(tái)有服務(wù)對(duì)應(yīng)的后端服務(wù)和端口是有動(dòng)態(tài)調(diào)整需求。架構(gòu)上是基礎(chǔ)組件需要進(jìn)行升級(jí),數(shù)據(jù)訪問層日志監(jiān)控系統(tǒng)等。 介紹 ? ? ? ?MaxLeap早期是一家研發(fā)、運(yùn)營移動(dòng)應(yīng)用和手機(jī)游戲公司,發(fā)展過程中積累了很多通用組件。這些組件很大程度幫公司在移動(dòng)研發(fā)過程中節(jié)省了時(shí)間和成本,...
摘要:將開發(fā)環(huán)境和生產(chǎn)環(huán)境的差異降至最低,并使用持續(xù)交付實(shí)施敏捷開發(fā)??梢栽诠ぞ呒軜?gòu)和開發(fā)流程不發(fā)生明顯變化的前提下實(shí)現(xiàn)擴(kuò)展。我們的初衷是分享在現(xiàn)代軟件開發(fā)過程中發(fā)現(xiàn)的一些系統(tǒng)性問題,并加深對(duì)這些問題的認(rèn)識(shí)。 簡(jiǎn)介 如今,軟件通常會(huì)作為一種服務(wù)來交付,它們被稱為網(wǎng)絡(luò)應(yīng)用程序,或軟件即服務(wù)(SaaS)。12-Factor 為構(gòu)建如下的 SaaS 應(yīng)用提供了方法論: 使用標(biāo)準(zhǔn)化流程自動(dòng)配置,從...
摘要:而要實(shí)現(xiàn)物物相連,一共有個(gè)階段性任務(wù),而這個(gè)階段性任務(wù),也伴隨著巨大的挑戰(zhàn)本文分享自華為云社區(qū)云駐共創(chuàng)以小窺大,從一盞路燈看億萬物聯(lián)網(wǎng)之路云駐共創(chuàng)以小窺大,從一盞路燈看億萬物聯(lián)網(wǎng)之路,作者啟明。 摘要:IoT, Internet of Things,物聯(lián)網(wǎng),顧名思義,是物物相連。而要實(shí)現(xiàn)物...
閱讀 1679·2021-09-02 15:41
閱讀 1082·2021-09-02 15:11
閱讀 1360·2021-07-28 00:15
閱讀 2443·2019-08-30 15:55
閱讀 1225·2019-08-30 15:54
閱讀 1769·2019-08-30 15:54
閱讀 3043·2019-08-30 14:02
閱讀 2597·2019-08-29 16:57