国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

如何寫一個無配置格式統(tǒng)一的日志

tulayang / 494人閱讀

摘要:背景大量項目在使用記日志,有部分項目使用日志混亂,格式不統(tǒng)一,多數(shù)人搞不懂配置文件,導(dǎo)致配置錯誤,現(xiàn)在需要開發(fā)一套統(tǒng)一的少配置的日志組件,使用方便。

背景

大量項目在使用logback記日志,有部分項目使用日志混亂,格式不統(tǒng)一,多數(shù)人搞不懂配置文件,導(dǎo)致配置錯誤,現(xiàn)在需要開發(fā)一套統(tǒng)一的、少配置的日志組件,使用方便。

設(shè)計思路

盡量采用0配置,無logback.xml

日志格式統(tǒng)一,方便后續(xù)日志分析系統(tǒng)

只有兩個日志級別,一個是正常日志,一個是異常日志

提供log4j、jcl、logback、commons-log等橋接方案及版本兼容方案

提子線程、json格式化輸出、map格式化、數(shù)組格式化、請求響應(yīng)參數(shù)(供耗時)等便捷日志輸出方法

支持redis、db、http自動開關(guān)配置**

新增日志類型(logger)

api采用流式結(jié)構(gòu),類似StringBuffer

概要設(shè)計 零配置

調(diào)研代碼

java
static LoggerContext lc;
    static {
        lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        // 對應(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();
        // 對應(yīng)配置中的logger
        ch.qos.logback.classic.Logger rootLogger = lc.getLogger("com.test");
        rootLogger.addAppender(ca);}

上面代碼等價于下面的xml

%d{MMddHHmmss.SSS} [%thread] %-5level %logger{36} - %msg%n

由此可以隨意把配置文件中的內(nèi)容以代碼形式編寫,理論已經(jīng)可以實現(xiàn)0配置。

輸出路徑

約定固定將日志輸出到,相對路徑log/xxx.yyyy-MM-dd-HH.log,其中xxx為logger的name

日志格式

格式固定:
MMddHHmmss.SSS||id||【交易名★子步驟】||context ||level
例:
150000.311||N-XrUTQzIc1531897200311||【CiTeeFilter★ci攔截器】||ci攔截器 請求的完整參數(shù)為:{"merchantId":["0012444"],"userId":["13112341232"]} ||INFO
固定格式的核心代碼,攔截到日志請求,按照格式拼裝,主要方法為繼承ThrowableProxyConverter和MessageConverter來實現(xiàn)對日志的攔截,并修改為想要的格式,其中使用的例如id等放到本地變量內(nèi),核心是對MDC的使用

基礎(chǔ)logger

所有日志都默認輸出到這里 logger name:service 系統(tǒng)初始化時,定義這個Logger和appender,即這個Logger為root log

自定義的logger

提供addLogger方法,參數(shù) packageName 包名,例如:com.test 必輸參數(shù) 如果name未設(shè)置時,name默認為包名最后一個.后面的字符 name 名字,決定日志文件的名字 非必輸 path 日志路徑 非必輸 additivity 是否輸出到root log內(nèi)

特殊的log
提供特殊組件的log配置,例如: redis 默認ERROR http 默認ERROR db連接池 默認ERROR kafka 默認ERROR schedul 默認ERROR spring 默認ERROR

異常、換行日志處理

提供exception異常棧格式打印 提供帶換行的格式化打印 代碼思路:繼承ThrowableProxyConverter,獲取異常棧,在每行的前面插入固定格式文本

普通日志api(VirgoLog)
方法 方法描述
setUniqKey(id) 設(shè)置當前線程id,線程開始時設(shè)置即可,后面無需設(shè)置
updateStep(trade, step) 更新當前id的步驟信息
log(msg, param) 記錄普通日志,msg替換規(guī)則,普通替換為{},如果想替換為業(yè)務(wù)日志api中的格式,使用``替換
logErr(msg, e) 記錄異常日志
log( trade, step, msg, param) 記錄普通日志,此方法會自動更新id、trade、step,不建議使用
logErr(trade, step, msg, e) 記錄異常日志
log(cid, trade, step, msg, param) 記錄普通日志,此方法會自動更新id、trade、step,不建議使用
logErr(cid, trade, step, msg, e) 記錄異常日志
debug(msg, param) 記錄debug級別日志,不建議使用
業(yè)務(wù)日志api(VirgoLog)

平時記日志時,如果某個類沒有時間toString方法,會無法正確打印出數(shù)據(jù),此時提供替換方法,直接將object替換為json打印,核心代碼思路為

MessageFormatter是處理{}替換的類,重新寫個類,稍加改動即支持{}也支持`` ,并判斷替換為json還是toString api如下

方法 方法描述
begin(msg) 記錄開始
end(msg) 記錄完成,會打印本線程內(nèi)上一個begin到現(xiàn)在的耗時
logJson(json, format) 記錄json格式化日志,format表示是否換行
logMap(map, format) 記錄map格式化日志
logCollection(list, format) 記錄集合格式化日志
logArray(array, format) 記錄數(shù)組格式化日志
logObjct(obj, format) 記錄Object格式化日志
系統(tǒng)api(LoggerHelper)
方法 方法描述
getLogger() 獲取logger,用于記日志
getLogger(name) 通過name獲取logger
addLogger() 參考自定義Logger,如果logger已經(jīng)創(chuàng)建,則不再創(chuàng)建,一般不使用,除非想自定義日志名等
consoleOpen() 打開控制臺日志,系統(tǒng)啟動時默認配置控制臺日志
commonOpen(name, level) 默認的組件都是error級別,這個方法可以變更日志級別,例如redis http等
特殊的格式化

map:即轉(zhuǎn)化為json,然后再格式化
collection:同上
array:也同上
object:同上

問題

1、密碼脫敏、加解密有必要多帶帶提取方法嗎

2、提供父線程打印開關(guān)

maven依賴
        
            com.cdc.ecliptic
            virgo
            1.5_1.6-SNAPSHOT
        
demo
public static void main(String[] args) throws InterruptedException {

        // 啟動
        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");
        // 打開控制臺
        LoggerHelper.consoleOpen();
        // 設(shè)置cid
        VirgoLog.setUniqKey(null);
        // 設(shè)置步驟名和交易名
        VirgoLog.updateStep("adfa", "saf");
        // 獲取Logger
        VirgoLog logger = VirgoLog.getLogger();

        // 打開debug級別(只有在開發(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("我只有一行");
        Map map = 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("我錯了:{},你沒錯:~~", new Exception("asdfsaflk"), "啊", map);
//        logger.log("----------------------------------------------");
//        // {}替換普通對象,調(diào)用toString()  ~~把對象轉(zhuǎn)換為json并且格式化輸出 ``把對象轉(zhuǎn)換為json不格式化輸出
        logger.log("你好{},你是誰~~``,sd~xx {}", map, map, map, "tttt");
        VirgoLog.updateStep("saf2");
//        // 把對象轉(zhuǎn)換為json輸出
//        logger.logJson(map, false);
//        // 更新步驟名和交易名
//        VirgoLog.updateStep("bbbbb", "ccccc");
//        // 耗時日志打印
        logger.begin("處理內(nèi)容");
        logger.begin("處理第二個");
        logger.begin("處理第三個");
        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ù)學院

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/72861.html

相關(guān)文章

  • 容器內(nèi)應(yīng)用日志收集方案

    摘要:容器化應(yīng)用日志收集挑戰(zhàn)應(yīng)用日志的收集分析和監(jiān)控是日常運維工作重要的部分,妥善地處理應(yīng)用日志收集往往是應(yīng)用容器化重要的一個課題。日志來源識別采用統(tǒng)一應(yīng)用日志收集方案,日志分散在很多不同容器的相互隔離的環(huán)境中,需要解決日志的來源識別問題。 容器化應(yīng)用日志收集挑戰(zhàn) 應(yīng)用日志的收集、分析和監(jiān)控是日常運維工作重要的部分,妥善地處理應(yīng)用日志收集往往是應(yīng)用容器化重要的一個課題。 Docker處理日志...

    ormsf 評論0 收藏0
  • 從應(yīng)用到平臺 - 云服務(wù)架構(gòu)演進過程

    摘要:應(yīng)用的研發(fā)上線運維運營形成閉環(huán),順利完成從對內(nèi)服務(wù)到公共平臺的升級。從功能角度,只能支持靜態(tài)方式設(shè)置反向代理,然后,而平臺有服務(wù)對應(yīng)的后端服務(wù)和端口是有動態(tài)調(diào)整需求。架構(gòu)上是基礎(chǔ)組件需要進行升級,數(shù)據(jù)訪問層日志監(jiān)控系統(tǒng)等。 介紹 ? ? ? ?MaxLeap早期是一家研發(fā)、運營移動應(yīng)用和手機游戲公司,發(fā)展過程中積累了很多通用組件。這些組件很大程度幫公司在移動研發(fā)過程中節(jié)省了時間和成本,...

    LiangJ 評論0 收藏0
  • 現(xiàn)代軟件開發(fā)流程-by 12-Factor

    摘要:將開發(fā)環(huán)境和生產(chǎn)環(huán)境的差異降至最低,并使用持續(xù)交付實施敏捷開發(fā)??梢栽诠ぞ呒軜?gòu)和開發(fā)流程不發(fā)生明顯變化的前提下實現(xiàn)擴展。我們的初衷是分享在現(xiàn)代軟件開發(fā)過程中發(fā)現(xiàn)的一些系統(tǒng)性問題,并加深對這些問題的認識。 簡介 如今,軟件通常會作為一種服務(wù)來交付,它們被稱為網(wǎng)絡(luò)應(yīng)用程序,或軟件即服務(wù)(SaaS)。12-Factor 為構(gòu)建如下的 SaaS 應(yīng)用提供了方法論: 使用標準化流程自動配置,從...

    draveness 評論0 收藏0
  • 以小窺大,從一盞路燈看億萬物聯(lián)網(wǎng)之路

    摘要:而要實現(xiàn)物物相連,一共有個階段性任務(wù),而這個階段性任務(wù),也伴隨著巨大的挑戰(zhàn)本文分享自華為云社區(qū)云駐共創(chuàng)以小窺大,從一盞路燈看億萬物聯(lián)網(wǎng)之路云駐共創(chuàng)以小窺大,從一盞路燈看億萬物聯(lián)網(wǎng)之路,作者啟明。 摘要:IoT, Internet of Things,物聯(lián)網(wǎng),顧名思義,是物物相連。而要實現(xiàn)物...

    appetizerio 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<