日志分類
- 登錄日志:登錄軌跡,檢測(cè)賬號(hào)安全性,統(tǒng)計(jì)用戶活躍度,刻畫(huà)用戶畫(huà)像,流動(dòng)情況。
- 退出日志:系統(tǒng)使用時(shí)長(zhǎng),留存期。
- 操作日志:用戶旅途
- 接口日志:接口交互頻率,接口性能,三方系統(tǒng)聯(lián)調(diào)的重要定位手段
- 程序日志:重要業(yè)務(wù),比如訂單創(chuàng)建、MQ消費(fèi)生產(chǎn)
- 埋點(diǎn)日志:用戶特定行為,產(chǎn)品運(yùn)營(yíng)數(shù)據(jù)分析
日志框架
- logback
- log4j
Java市面上主流的就是這兩種日志框架,引入依賴后就能結(jié)合Spring一起使用。
要使用日志門(mén)面模式的接口,而不是耦合具體的框架,Java日志的門(mén)面叫做SLF4J(Simple logging Facade for Java )。他是一個(gè)標(biāo)準(zhǔn)接口。也符合架構(gòu)設(shè)計(jì)中的依賴抽象,而不是具體。
目前大部分都使用logback,log4j前段時(shí)間頻頻報(bào)出漏洞影響了好多關(guān)聯(lián)框架~當(dāng)然logback也有。
tip: 使用lombok 在類上加@Slf4j注解即可直接用log對(duì)象來(lái)打印日志
日志等級(jí)
- fatal 致命、極其嚴(yán)重的錯(cuò)誤,可能會(huì)導(dǎo)致程序終止或崩潰
- error 錯(cuò)誤級(jí)別最高,用于運(yùn)行時(shí)異?;蛘咦远x的業(yè)務(wù)嚴(yán)重異常
- warn 有點(diǎn)問(wèn)題,但是不會(huì)影響大局
- info 業(yè)務(wù)型日志,一般用于rest請(qǐng)求參數(shù)和返回值、重要業(yè)務(wù)流程節(jié)點(diǎn)
- debug 調(diào)試過(guò)程,用于更多程序相關(guān)開(kāi)發(fā)者關(guān)注的日志
- trace 很少見(jiàn),用于跟蹤鏈路
他們的級(jí)別也按照順序排列。等級(jí)越低的日志越?jīng)]那么重要。
日志歸檔、留存期、分文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- 配置文件修改時(shí)重新加載,默認(rèn)true -->
<configuration scan="true">
<!--定義日志文件的存儲(chǔ)地址 勿在 LogBack 的配置中使用相對(duì)路徑-->
<property name="CATALINA_BASE" value="**/logs"></property>
<!-- 控制臺(tái)輸出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="UTF-8">
<!-- 輸出日志記錄格式 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 第一個(gè)文件輸出,每天產(chǎn)生一個(gè)文件 -->
<appender name="FILE1" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 輸出文件路徑+文件名 -->
<fileNamePattern>${CATALINA_BASE}/aa.%d{yyyyMMdd}.log</fileNamePattern>
<!-- 保存30天的日志 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<!-- 輸出日志記錄格式 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="CUSTOM" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${CATALINA_BASE}/custom.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${CATALINA_BASE}/custom.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 設(shè)置日志輸出級(jí)別 -->
<root level="ERROR">
<appender-ref ref="CONSOLE" />
</root>
<logger name="file1" level="DEBUG">
<appender-ref ref="FILE1" />
</logger>
<logger name="file1" level="INFO">
<appender-ref ref="FILE2" />
</logger>
<!-- 自定義logger -->
<logger name="custom" level="INFO">
<appender-ref ref="CUSTOM" />
</logger>
</configuration>
每個(gè)xml節(jié)點(diǎn)的類都是可以自定義的,比如歸檔后的日志文件權(quán)限只能是440以下,log4j就又一個(gè)
filePermissions的配置,而logback不支持這個(gè)屬性,只能繼承ch.qos.logback.core.rolling.TimeBasedRollingPolicy類,重寫(xiě)內(nèi)部的文件權(quán)限設(shè)置方法。
日志安全性
隱私數(shù)據(jù)脫敏
隱私數(shù)據(jù)包含了密碼、token、秘鑰、電話號(hào)碼、手機(jī)號(hào)、郵箱等等,這些都是業(yè)務(wù)數(shù)據(jù),IT運(yùn)維時(shí)需要脫敏。一般會(huì)在這幾種場(chǎng)景下打印
1、打印了接口的所有入?yún)?,若修改密碼 這種場(chǎng)景很容易出現(xiàn)
2、遠(yuǎn)程調(diào)用三方接口打印入?yún)?br>
3、查詢數(shù)據(jù)庫(kù)是打印返回值
4、數(shù)據(jù)處理時(shí)有意打印
那怎么解決呢?
- 不打印敏感字段,若實(shí)體類用的lombok,剛好又用toString來(lái)打印這個(gè)對(duì)象,就可以在字段上加
@ToString.Exclude,避免打印 - 脫敏,繼承日志消息轉(zhuǎn)換器
MessageConverter重寫(xiě)convert方法,將要打印的字符串通過(guò)正則匹配敏感信息,再替換成如138***1111的字符串。 - 聲明變量名為
transient,讓其在序列化時(shí)忽略,但是要注意使用場(chǎng)景。
日志注入
用戶輸入的參數(shù)未做任何驗(yàn)證直接寫(xiě)入日志文件,導(dǎo)致攻擊者可以通過(guò)特殊字符(\r \n)在日志中注入新的日志條目,破壞系統(tǒng)日志的完整性。
審計(jì)日志
管理界面對(duì)數(shù)據(jù)的增、改、查都非常重視,因?yàn)橐粋€(gè)小改動(dòng)都有可能對(duì)系統(tǒng)造成深遠(yuǎn)影響,所以需要審計(jì)日志,并且根據(jù)重要程度還需要落庫(kù)。一個(gè)合格的審計(jì)日志應(yīng)該有以下信息
- 來(lái)源ip
- 操作資源
- 操作類型(增?改?查)
- 涉及修改和刪除,要打印部分之前重要數(shù)據(jù),用于回滾
- 時(shí)間
- 操作人,這抓到就是一頓批
一般可以用AOP來(lái)實(shí)現(xiàn)對(duì)應(yīng)方法的日志記錄,在方法上加自定義的@AuditLog注解。
日志存儲(chǔ)
分布式日志
常見(jiàn)的有ELK,EFK等技術(shù)。ELK是ElasticSearch+Logstash+Kibana,而EFK是將Logstash換成了FlieBeat。更加的輕量。
分布式集群部署的場(chǎng)景下,日志分散在各個(gè)微服務(wù)docker中
存儲(chǔ)性能
寫(xiě)日志是一個(gè)寫(xiě)磁盤(pán)的操作,作為日志記錄應(yīng)該要和業(yè)務(wù)進(jìn)行解耦,這里建議使用異步的方式(線程池、內(nèi)存隊(duì)列、MQ)記錄日志。
存儲(chǔ)介質(zhì)
一般是直接寫(xiě)磁盤(pán)里,但是為了數(shù)據(jù)分析,也用到了數(shù)據(jù)庫(kù),如
- MongoDB 存儲(chǔ)報(bào)文,不規(guī)則數(shù)據(jù)
- MySQL 日志流水、訂單交易需要查詢排序的數(shù)據(jù)
- ES 適用所有日志
應(yīng)用組件日志
mysql
數(shù)據(jù)庫(kù)的日志作用就更強(qiáng)大了,可以用來(lái)做數(shù)據(jù)回滾,數(shù)據(jù)備份,數(shù)據(jù)同步等等操作。
- redolog 記錄數(shù)據(jù)的物理變化 InnoDB引擎獨(dú)有的能力
- undolog 回滾(binlog相反的SQL)和多版本控制(MVCC)
- binlog 用于復(fù)制和恢復(fù)數(shù)據(jù),記錄所有用戶的增刪改操作,主從同步也是依賴該日志
- 慢日志
Nginx & tomcat
- access.log 訪問(wèn)日志,主要用于看用戶接口層面的瀏覽軌跡,以及響應(yīng)碼是否符合預(yù)期,報(bào)表統(tǒng)計(jì)接口、QPS、各個(gè)狀態(tài)碼的分布。