tomcat--catalina-daemon.out日志分割和输出等级控制

    为了更加安全,生产环境中我更加青睐把tomcat 使用 jsvc 以守护进程的方式启动(daemon.sh )。这样tomcat自身将会生成另外一个日志文件(catalina-daemon.out),而不是之前的catalina.out。但是随之出现2个问题:1.catalina-daemon.out这个文件不会自动切割,而且会无线增大。2.catalina-daemon.out里面log输出等级无法更改,大量info信息占据了磁盘。为了针对这两个问题特意研究了一番,研究过程因功力尚浅所以并不专业,敬请谅解。


一.catalina-daemon.out自动切割问题。

    第一时间看到这个问题,首先想到的是类似于nginx的log切割方法。于是从daemon.sh里找到了它输出的路径,大约在136行。

test ".$CATALINA_OUT" = . && CATALINA_OUT="$CATALINA_BASE/logs/catalina-daemon.out"

可以直接更改到我们指定的目录下,并且用时间方式命名

test ".$CATALINA_OUT" = . && CATALINA_OUT="/XXX/catalina-daemon%Y-%m-%d.out"

但是使用这种方式每次更改需要重新启动tomcat才会生效。tomcat不像nginx拥有平滑重启的功能,每次重启都需要重新加载项目会直接导致项目中断,并不适合线上环境使用,故而pass掉。


    于是百度了一下,但是并没有发现太好的解决办法。网上更多的是通过通过cronlog这个工具对catalina.out这个文件进行分割,死马当活马医于是尝试了一下仿照使用,把文件更改为

test ".$CATALINA_OUT" = . && CATALINA_OUT="|/usr/local/sbin/cronolog $CATALINA_BASE/logs/catalina-daemon%Y-%m-%d.out"

但是并没有生效,不知道是不是我用错了。


    又想我重新生产成一个catalina-daemon.out,把之前的mv成123.log(随便起的名,方便后面更加直观说明,语文没学好)是否可以解决这个问题?但是我发现再不重启的前提下,tomcat会持续在123.log这个文件继续输出。当时便百度了一个linux文件标示的知识,发现也仅仅有inode,并不会产生一个唯一的文件标示符。google了一下大概意思是说tomcat启动后会把这个文件直接映射到内存中,也就是tomcat启动时的虚拟机里,不是按照路径+文件名的方式进行输出。那我要直接从内存这块里修改呢?因为确实能力有限,就没有做再深入的研究。


    无奈之下只能选用一个最简单暴力的方法,算是临时解决了一下问题,发现网上有就给copy过来,具体如下:

#!/bin/bash
thedate=`date --rfc-3339=date`
predate=`date +%Y-%m-%d --date="-7 day"`

rmfile="/xxxx/server/tomcat/logs/catalina-daemon.${predate}.out"
outfile="/xxxx/server/tomcat/logs/catalina-daemon.out"
if [ -f ${rmfile} ];then
   rm -f ${rmfile}
fi

if [ -f ${outfile} ];then
   cp ${outfile} /xxxx/server/tomcat/logs/catalina-daemon.${thedate}.out
   echo "" > ${outfile}
fi

exit 0

    不过这样做有可能会丢失一小部分日志,不知道有没有更好的解决办法。还看到有人用logrotate,不过这里就没有做实验。如果大家有更好的办法,欢迎指教。

    

二.catalina-daemon.out输出等级问

    catalina-daemon.out跟catalina.out文件一样,是存放着控制台输出的日志。但是默认情况是info级别,大量的info信息充斥着整个文件,所以我们应该把等级设置为WARNING来屏蔽掉这些输出信息。

SEVERE (highest value) >WARNING >INFO >CONFIG >FINE >FINER >FINEST  (lowest value)

一说到更改log第一反应是修改tomcat conf下的logging.properties的文件,但是发现更改后并没有生效。

    返回来去读了一下deamon.sh,发现下面145行,log配置文件路径:

if [ -z "$LOGGING_CONFIG" ]; then
  if [ -r "$CATALINA_BASE/conf/logging.properties" ]; then
    LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
  else
    # Bugzilla 45585
    LOGGING_CONFIG="-Dnop"
  fi
fi

以及第200行,启动配置

     start   )
       "$JSVC" $JSVC_OPTS \
       -java-home "$JAVA_HOME" \
       -user $TOMCAT_USER \
       -pidfile "$CATALINA_PID" \
       -wait "$SERVICE_START_WAIT_TIME" \
       -outfile "$CATALINA_OUT" \
       -errfile "&1" \
       -classpath "$CLASSPATH" \
       "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \
       -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
       -Dcatalina.base="$CATALINA_BASE" \
       -Dcatalina.home="$CATALINA_HOME" \
       -Djava.io.tmpdir="$CATALINA_TMP" \
       $CATALINA_MAIN
       exit $?

    发现启动的时候确实是读取了logging.properties这个文件,同时也发现了把控制台的标准输出跟错误输出一起都输出到$CATALINA_OUT下面,但是为什么更改后没有生效呢?无奈之下只能硬着头皮去看看tomcat源码。

    说实话读源码真是要命,但是发现源码里有读取JDK下面的logging.properties,更改后发现无效。继续看

    wKioL1aEnJ3Trc5HAACC9DabZtI682.png

发现在源码里已经定了log输出等级为INFO,难道只能去修改源码重新编译tomcat才能生效么?

    后来请教一位大神重新帮我解读源码,已经找到了问题所在,感谢大神小果儿。大致如下(个人理解)

    首先 tomcat日志上有 目标源,同一个源可以有多个目标输出,同样多个源也可以对应一个输出。我们之前所更改的配置文件其实都生效了,只是对应的输出不对而已。在jsvc下定义的catalina-deamon.out的源是在tomcat项目(webapp)下,所以想要修改catalina-deamon.out的输出等级只需要更改项目下logging.properties文件就可以生效,如果有多个项目则需要到每个项目下修改。顺便一提。catalina.out对应的源是tomcat自身,所以更改tomcat下的配置文件就可以生效。

你可能感兴趣的:(tomcat)