首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Tomcat 訪問日誌清理實戰:擴展 AccessLogValve 實現定期/定量刪除

     編輯:Java 綜合教學

Tomcat 訪問日誌清理實戰:擴展 AccessLogValve 實現定期/定量刪除

Tomcat 默認不清理訪問日誌,長期運行會佔用大量磁盤空間。本文介紹開啟訪問日誌、擴展 AccessLogValve 實現自動清理(按大小/按時間),以及普通日誌配置 Log4j 回滾方案。

啟用訪問日誌

編輯 ${catalina}/conf/server.xml,取消註釋 AccessLogValve:

<Valve className="org.apache.catalina.valves.AccessLogValve"
       directory="logs"
       prefix="localhost_access_log."
       suffix=".txt"
       pattern="common"
       resolveHosts="false" />

關鍵屬性:directory 日誌目錄、prefix/suffix 文件名前綴後綴、pattern 日誌格式、rotatable 是否按日期滾動。

擴展 AccessLogValve 實現自動清理

繼承 AccessLogValve 並重寫 log() 方法,在寫入日誌時執行清理邏輯:

public class CustomAccessLogValve extends AccessLogValve {
    
    @Override
    public void log(Request request, Response response, long time) {
        super.log(request, response, time);
        emptyFile();  // 每次寫入檢查是否需要清理
    }
    
    public void emptyFile() {
        String logPath = System.getProperty("catalina.base");
        
        if (!rotatable) {  // 單文件模式:按大小清理
            synchronized (this) {
                if (currentLogFile.length() > 10 * 1024) {  // 超過 10KB
                    currentLogFile.delete();
                    open();  // 重新打開文件
                }
            }
        } else {  // 多文件模式:按時間清理
            File dir = new File(logPath);
            if (dir.isDirectory()) {
                File[] logs = dir.listFiles();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd.HH.mm");
                for (File log : logs) {
                    // 解析文件名中的時間:localhost_access_log.2016-12-16.23.37.log
                    String name = log.getName();
                    int start = name.indexOf(".") + 1;
                    int end = name.lastIndexOf(".");
                    String dateStr = name.substring(start, end);
                    try {
                        long logTime = sdf.parse(dateStr).getTime();
                        // 超過 10 分鐘刪除
                        if ((System.currentTimeMillis() - logTime) / (1000 * 60) > 10) {
                            log.delete();
                            open();
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

配置自定義 Valve

在 server.xml 中使用全類名:

<Valve className="com.example.CustomAccessLogValve"
       directory="logs"
       prefix="localhost_access_log."
       suffix=".log"
       pattern="%h %l %u %t "%r" %s %b"
       rotatable="true" />

普通日誌配置 Log4j 回滾

catalina.out、localhost.log 等普通日誌建議接入 Log4j2:

<Configuration>
  <Appenders>
    <RollingFile name="CatalinaLog" fileName="${sys:catalina.base}/logs/catalina.log"
                 filePattern="${sys:catalina.base}/logs/catalina-%d{yyyy-MM-dd}.log.gz">
      <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
      <Policies>
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <SizeBasedTriggeringPolicy size="100 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="30"/>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="INFO">
      <AppenderRef ref="CatalinaLog"/>
    </Root>
  </Loggers>
</Configuration>

總結

擴展 AccessLogValve 實現業務級清理邏輯靈活可控;普通日誌強烈建議接入成熟日誌框架(Log4j2/Logback)統一管理回滾策略,避免手動維護腳本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved