Tomcat 中 catalina.out、catalina.log、localhost.log 和 access_log 的區別

程式設計師自由之路發表於2020-09-27

開啟 Tomcat 安裝目錄中的 log 資料夾,我們可以看到很多日誌檔案,這篇文章就來介紹下這些日記檔案的具體區別。

catalina.out 日誌

catalina.out 日誌檔案是 Tomcat 的標準輸出(stdout)和標準出錯(stderr)輸出的“目的地”。我們在應用裡使用System.out列印的內容都會輸出到這個日誌檔案中。另外,如果我們在應用裡使用其他的日誌框架,配置了向 Console 輸出日誌,則也會輸出到這個檔案。

這個日誌設定是在 Tomcat 的啟動指令碼中指定的。下面是 Linux 下 Tomcat 的一段啟動指令碼:

shift
  # 建立 catalina.out 日誌檔案
  touch "$CATALINA_BASE"/logs/catalina.out
  if [ "$1" = "-security" ] ; then
    echo "Using Security Manager"
    shift
    "$_RUNJAVA" $JAVA_OPTS "$LOGGING_CONFIG" $CATALINA_OPTS \
      -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \
      -Djava.security.manager \
      -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \
      -Dcatalina.base="$CATALINA_BASE" \
      -Dcatalina.home="$CATALINA_HOME" \
      -Djava.io.tmpdir="$CATALINA_TMPDIR" \
      org.apache.catalina.startup.Bootstrap "$@" start \
      # 向 catalina.out 中追加日誌內容
      >> "$CATALINA_BASE"/logs/catalina.out 2>&1 &

    if [ ! -z "$CATALINA_PID" ]; then
        echo $! > $CATALINA_PID
      fi

上面的指令碼比較簡單,就不深入介紹了。如果我們用 Windows 上的 Tomcat 的話,你會發現並沒有 catalina.out 這個日誌檔案生成。但是 Tomcat 啟動的時候會彈出一個新的終端來顯示日誌,這個也是在啟動指令碼中設定的。下面是一個 Window 下一個真實的啟動命令:

"start "Tomcat" "C:\Program Files\Java\jdk1.8.0_73\bin\java.exe" -Djava.util.logging.config.file="D:\software\tomcat-64\apache-tomcat-9.0.0.M21-windows-x64 (1)\apache-tomcat-9.0.0.M21\conf\logging.properties" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager  "-Djdk.tls.ephemeralDHKeySize=2048" -Djava.protocol.handler.pkgs=org.apache.catalina.webresources   -classpath "D:\software\tomcat-64\apache-tomcat-9.0.0.M21-windows-x64 (1)\apache-tomcat-9.0.0.M21\bin\bootstrap.jar;D:\software\tomcat-64\apache-tomcat-9.0.0.M21-windows-x64 (1)\apache-tomcat-9.0.0.M21\bin\tomcat-juli.jar" -Dcatalina.base="D:\software\tomcat-64\apache-tomcat-9.0.0.M21-windows-x64 (1)\apache-tomcat-9.0.0.M21" -Dcatalina.home="D:\software\tomcat-64\apache-tomcat-9.0.0.M21-windows-x64 (1)\apache-tomcat-9.0.0.M21" -Djava.io.tmpdir="D:\software\tomcat-64\apache-tomcat-9.0.0.M21-windows-x64 (1)\apache-tomcat-9.0.0.M21\temp" org.apache.catalina.startup.Bootstrap arg1 arg2 start"

上面命令中開頭的start Tomcat的意思是重新開啟一個叫 Tomcat 的視窗執行 Java 命令。這個啟動命令中並沒有建立 catalina.out 這個日誌檔案,所以我們在 Window 平臺上並不能看到 catalina.out 這個檔案。

如果你也想要建立這個日誌檔案的話,可以修改啟動指令碼。

:doStart
shift
if "%TITLE%" == "" set TITLE=Tomcat
# set _EXECJAVA=start "%TITLE%" %_RUNJAVA%
# 第一步:不再重新開啟一個 Tomcat 終端
set _EXECJAVA= %_RUNJAVA%

將日誌追加到 catalina.out 日誌檔案。

rem Execute Java with the applicable properties
if not "%JPDA%" == "" goto doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
%_EXECJAVA% %CATALINA_LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% >>%CATALINA_HOME%/logs/catalina.out
goto end
:doSecurity
%_EXECJAVA% %CATALINA_LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda
%_EXECJAVA% %CATALINA_LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %JPDA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doSecurityJpda
%_EXECJAVA% %CATALINA_LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %JPDA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end

注意點:隨著系統上線的時間越來越長, catalina.out 會變得很大,所以最好還是要設定一些定時任務來清理歸檔這個日誌檔案。

catalina.YYYY-MM-DD.log 日誌

catalina.{yyyy-MM-dd}.log 是 Tomcat 自己執行的一些日誌,主要記錄 Tomcat 在啟動和暫停時的執行內容。

localhost.YYYY-MM-DD.log

localhost.{yyyy-MM-dd}.log 主要是應用初始化(listener, filter, servlet)未處理的異常最後被 Tomcat 捕獲而輸出的日誌,它也是包含 Tomcat 的啟動和暫停時的執行日誌,但它沒有 catalina.YYYY-MM-DD.log 日誌全。

localhost_access_log.YYYY-MM-DD.txt

Tomcat 的請求訪問日誌,請求的時間,請求的型別,請求的資源和返回的狀態碼都有記錄。配置這個日誌非常有必要,可以讓我們清楚的看清請求的狀況。

1. 傳統配置方式

預設配置在 server.xml 中,如下:

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

注意,xml中的 " 代表 " 具體原因自行查閱

在該配置下格式為

192.168.10.66 - - [26/Feb/2020:17:52:00 +0800] "GET /getIndex HTTP/1.1" 200 54 1

官方支援的配置如下:

%a - 遠端訪問的客戶端IP
%A - Server服務所在的伺服器自身IP
%b - 傳送的位元組數,不包含httpHeader 如果是0的話顯示為 -
%B - 傳送的位元組數,不包含httpHeader
%h - 遠端的客戶端伺服器名稱(如果resolve host為false則即為IP)
%H - 請求協議名稱
%l - 遠端請求用來認證的使用者名稱 (一直是 '-')
%m - 請求方法 (GET, POST, 等.)
%p - 接收請求的本地埠
%q - 請求中的查詢引數 (如果有的話,以?開頭) (例如 /getIndex?id=3,其中'?id=3'就是)
%r - 請求的第一行 (方法和請求地址)
%s - 返回結果對應的http code
%S - 使用者的 session id
%t - 日期和時間,使用普通Log形式展示
%u - 遠端訪問的已認證的使用者 (如果有的話), 沒有的話顯示 '-'
%U - 請求的url路徑
%v - 本地服務所在伺服器名稱
%D - 處理這個請求的時間, 毫秒錶示
%T - 處理這個請求的時間, 以秒錶示
%I - 當前請求的執行緒名稱 (可以在呼叫棧中用來做比較和查詢)

2. Spring Boot 中的配置

在 Spring Boot 中使用的是內嵌的 Tomcat,也支援對 access_log的配置。

server:
  tomcat:
    #最好進行這段配置,預設會在tmp目錄下建立,Linux有時會有定時任務刪除tmp目錄下的內容
    basedir: my-tomcat
    accesslog:
      enabled: true
      pattern: '%t %a "%r" %s %S (%b M) (%D ms)'

Spring Boot 中關於 access_log 的配置項還有很多,用的時候可以自行參考官方文件。

參考

相關文章