應(yīng)用日志雜談

日志分類

  1. 登錄日志:登錄軌跡,檢測(cè)賬號(hào)安全性,統(tǒng)計(jì)用戶活躍度,刻畫(huà)用戶畫(huà)像,流動(dòng)情況。
  2. 退出日志:系統(tǒng)使用時(shí)長(zhǎng),留存期。
  3. 操作日志:用戶旅途
  4. 接口日志:接口交互頻率,接口性能,三方系統(tǒng)聯(lián)調(diào)的重要定位手段
  5. 程序日志:重要業(yè)務(wù),比如訂單創(chuàng)建、MQ消費(fèi)生產(chǎn)
  6. 埋點(diǎn)日志:用戶特定行為,產(chǎn)品運(yùn)營(yíng)數(shù)據(jù)分析

日志框架

  1. logback
  2. 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í)有意打印

那怎么解決呢?

  1. 不打印敏感字段,若實(shí)體類用的lombok,剛好又用toString來(lái)打印這個(gè)對(duì)象,就可以在字段上加@ToString.Exclude,避免打印
  2. 脫敏,繼承日志消息轉(zhuǎn)換器MessageConverter 重寫(xiě)convert方法,將要打印的字符串通過(guò)正則匹配敏感信息,再替換成如 138***1111的字符串。
  3. 聲明變量名為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)該有以下信息

  1. 來(lái)源ip
  2. 操作資源
  3. 操作類型(增?改?查)
  4. 涉及修改和刪除,要打印部分之前重要數(shù)據(jù),用于回滾
  5. 時(shí)間
  6. 操作人,這抓到就是一頓批

一般可以用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ù),如

  1. MongoDB 存儲(chǔ)報(bào)文,不規(guī)則數(shù)據(jù)
  2. MySQL 日志流水、訂單交易需要查詢排序的數(shù)據(jù)
  3. 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)碼的分布。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容