Tomcat 中 catalina.out、catalina.log、localhost.log 和 access_log 的区别

打开 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 的配置项还有很多,用的时候可以自行参考官方文档。

参考

Tags: