Log4j日志分類和過濾敏感字段的實(shí)例
項(xiàng)目上線時(shí),需要對項(xiàng)目做安全檢查,其中有兩項(xiàng)是對輸出日志進(jìn)行分類和過濾掉日志中敏感字段。
項(xiàng)目使用Log4j日志系統(tǒng),下面簡單介紹下這兩項(xiàng)要求的實(shí)現(xiàn)方式。
對日志進(jìn)行分類,要求調(diào)用其他服務(wù)的API日志按照格式單獨(dú)輸出到一個(gè)文件。
方式: 除根Logger外,再額外增加一個(gè)apiLogger,如下,
<!-- api logger的設(shè)置--> <logger name="log4j.logger.apiLogger" additivity="false"> <level value ="INFO"/> <appender-ref ref="apiConsoleAppender"/> <appender-ref ref="apiMsgOutGoingAppender"/> </logger> <!-- 根logger的設(shè)置--> <root> <level value ="INFO"/> <appender-ref ref="ConsoleAppender"/> <appender-ref ref="DailyRollingFileAppender"/> </root>
注: (1) additivity設(shè)為false,則root中的配置就失效了。即使用root配置的日志不會(huì)在apiLogger的文件中出現(xiàn);
(2) 每種logger指定兩個(gè)appender,分別是在debug console和Linux 服務(wù)器日志文件中顯示。
根日志的ConsoleAppender和DailyRollingFileAppender的配置如下:
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<!-- 設(shè)置日志輸出的樣式 -->
<layout class="org.apache.log4j.PatternLayout">
<!-- 設(shè)置日志輸出的格式 -->
<param name="ConversionPattern" value="**** [%p] [%d{yyyy/MM/dd HH:mm:ss:SSS}] ******************************%n[Thread] %t%n[Class] %C%n[Method] %M%n[Message] %m%n%n" />
</layout>
</appender>
<appender name="DailyRollingFileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<!-- 設(shè)置日志信息輸出文件全路徑名 -->
<param name="File" value="/var/log/tomcat/hpc.log" />
<!-- 設(shè)置日志多久回滾一次,即產(chǎn)生一個(gè)新的日志文件 -->
<param name="DatePattern" value="'_'yyyy-MM-dd" />
<!--日志編碼格式-->
<param name="Encoding" value="UTF-8" />
<!-- 設(shè)置是否在重新啟動(dòng)服務(wù)時(shí),在原有日志的基礎(chǔ)添加新日志 -->
<param name="Append" value="true" />
<!-- 設(shè)置日志輸出的樣式 -->
<layout class="org.apache.log4j.PatternLayout">
<!-- 設(shè)置日志輸出的格式 -->
<param name="ConversionPattern" value="**** [%p] [%d{yyyy/MM/dd HH:mm:ss:SSS}] *************************%n[Thread] %t%n[Class] %C%n[Method] %M%n[Message] %m%n%n" />
</layout>
<!-- 日志過濾: adminPass, X-Auth-Token; 包含該字符串的信息不輸出 -->
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="adminPass" />
<param name="AcceptOnMatch" value="false" />
</filter>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="X-Auth-Token" />
<param name="AcceptOnMatch" value="false" />
</filter>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="PW" />
<param name="AcceptOnMatch" value="false" />
</filter>
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="pwd" />
<param name="AcceptOnMatch" value="false" />
</filter>
<!-- password Password-->
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="assword" />
<param name="AcceptOnMatch" value="false" />
</filter>
<!-- 過濾pstmt-, 所有的數(shù)據(jù)庫操作均包含此字符串-->
<filter class="org.apache.log4j.varia.StringMatchFilter">
<param name="StringToMatch" value="pstmt-" />
<param name="AcceptOnMatch" value="false" />
</filter>
</appender>
apiLogger的apiConsoleAppender和apiMsgOutGoingAppender設(shè)置如下:
<!-- 將日志信息輸出到文件,可以配置多久產(chǎn)生一個(gè)新的日志信息文件 -->
<appender name="apiConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<!-- 設(shè)置日志輸出的樣式 -->
<layout class="org.apache.log4j.PatternLayout">
<!-- 設(shè)置日志輸出的格式 -->
<param name="ConversionPattern" value='[%-5p] [Outgoing] %X{og.serverIp} [%d{yyyy-MM-dd HH:mm:ss,SSS z}] %X{og.respTime} "%X{og.visitUri}" %X{og.statusCode} %X{og.reqLen} %X{og.respLen} %n' />
</layout>
</appender>
<appender name="apiMsgOutGoingAppender" class="org.apache.log4j.RollingFileAppender">
<!-- 設(shè)置日志信息輸出文件全路徑名 -->
<param name="File" value="/var/log/tomcat/interface.log" />
<!--日志編碼格式-->
<param name="Encoding" value="UTF-8" />
<!-- 設(shè)置是否在重新啟動(dòng)服務(wù)時(shí),在原有日志的基礎(chǔ)添加新日志 -->
<param name="Append" value="true" />
<!-- 設(shè)置文件最大size -->
<param name="MaxFileSize" value="30MB" />
<!-- 保留日志文件數(shù)的最大值 -->
<param name="MaxBackupIndex" value="100" />
<!-- 設(shè)置日志輸出的樣式 -->
<layout class="org.apache.log4j.PatternLayout">
<!-- 設(shè)置日志輸出的格式 -->
<param name="ConversionPattern" value='[%-5p] [Outgoing] %X{og.serverIp} [%d{yyyy-MM-dd HH:mm:ss,SSS z}] %X{og.respTime} "%X{og.visitUri}" %X{og.statusCode} %X{og.reqLen} %X{og.respLen} %n'/>
</layout>
</appender>
注:(1) Log4j系統(tǒng)Appender組件負(fù)責(zé)日志的輸出配置,包括輸出目錄,最大輸出大小,輸出文件數(shù)等;Layout組件負(fù)責(zé)日志輸出的格式。
(2)JAVA代碼在使用日志系統(tǒng)時(shí),默認(rèn)用根日志的配置輸出,若想使用apiLogger,使用:
private static Logger log = Logger.getLogger("log4j.logger.apiLogger");
(3)日志layout中傳入自定義參數(shù),使用MDC類:
public static void configAndPrintAPILogger(Logger logger, int statusCode, String method, String url,
long responseTime,
int requestLength, int responseLength)
{
String endpoint = url.split("/")[2];
MDC.put("og.serverIp", endpoint);
MDC.put("og.respTime", responseTime);
//截取 https://endpoint之后的
MDC.put("og.visitUri", method + " " + url.substring(8 + endpoint.length()));
MDC.put("og.statusCode", statusCode);
MDC.put("og.reqLen", requestLength);
MDC.put("og.respLen", responseLength);
logger.info("");
}
經(jīng)上述配置后,日志的輸出如下:

2. 日志中過濾敏感字符,如password, PW, adminPass等。如DailyRollingFileAppender中所示,使用StringMatchFilter:
<!-- 過濾password Password--> <filter class="org.apache.log4j.varia.StringMatchFilter"> <param name="StringToMatch" value="assword" /> <param name="AcceptOnMatch" value="false" /> </filter>
StringMatchFilter中使用msg.indexOf(StringToMatch)參數(shù)判斷是否過濾,即該條日志包含指定字段,若AcceptOnMatch設(shè)置為false,則不輸出。
需要注意的是,log4j日志系統(tǒng)采用xml格式時(shí)才能用該種方式過濾,properties格式時(shí)不能用此方法。
補(bǔ)充知識:解決日志log4j,slf4j,logback沖突問題
問題描述:
啟動(dòng)tomcat,發(fā)現(xiàn)tomcat無法啟動(dòng),catalina.out有如下錯(cuò)誤日志:
INFO [localhost-startStop-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.listenerStop Exception sending context destroyed event to listener instance of class org.springframework.web.context.ContextLoaderListener java.lang.NoClassDefFoundError: Could not initialize class org.apache.log4j.Log4jLoggerFactory at org.apache.log4j.LogManager.getLogger(LogManager.java:44) at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:270) at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:156) at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:274) at org.springframework.web.context.ContextCleanupListener.<clinit>(ContextCleanupListener.java:43) at org.springframework.web.context.ContextLoaderListener.contextDestroyed(ContextLoaderListener.java:145) at org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:4860) at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5495) at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:224) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:159) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
問題分析:
檢查lib庫下面,發(fā)現(xiàn)今天更新過log4j和logback組合,總共有如下包:
slf4j-api-1.7.5.jar
slf4j-log4j12-1.6.1.jar
log4j-1.2.16.jar
log4j-over-slf4j-1.7.5.jar
logback-core-1.1.2.jar
logback-classic-1.1.2.jar
通過查詢資料發(fā)現(xiàn),包slf4j-log4j12-1.6.1.jar 和log4j有沖突。
解決方法:
刪除后正常,刪除這個(gè):slf4j-log4j12-1.6.1.jar
附件常見組合:
log4j+slf4j
slf4j-api-1.7.5.jar
slf4j-log4j12-1.6.1.jar
log4j-1.2.16.jar
slf4j+logback
logback-core-1.1.2.jar
logback-classic-1.1.2.jar
slf4j-api-1.7.5.jar
以上這篇Log4j日志分類和過濾敏感字段的實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
jackson在springboot中的使用方式-自定義參數(shù)轉(zhuǎn)換器
這篇文章主要介紹了jackson在springboot中的使用方式-自定義參數(shù)轉(zhuǎn)換器,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
解決RestTemplate加@Autowired注入不了的問題
這篇文章主要介紹了解決RestTemplate加@Autowired注入不了的問題,具有很好的參考價(jià)值,希望對大家有所幫助。2021-08-08
SpringBoot中TransactionTemplate事務(wù)管理的實(shí)現(xiàn)
Spring Boot提供了多種方式來管理事務(wù),其中之一是使用TransactionTemplate,本文主要介紹了SpringBoot中TransactionTemplate事務(wù)管理的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
Java設(shè)計(jì)模塊系列之書店管理系統(tǒng)單機(jī)版(三)
這篇文章主要為大家詳細(xì)介紹了Java單機(jī)版的書店管理系統(tǒng)設(shè)計(jì)模塊和思想第三章,感興趣的小伙伴們可以參考一下2016-08-08

