【问题标题】:How to rotate Tomcat Access Log file, by file size rather than by the date如何按文件大小而不是按日期轮换 Tomcat 访问日志文件
【发布时间】:2016-04-14 05:34:19
【问题描述】:

目前我的访问日志文件(access_log.yyyy-MM-dd.log)每天都在生成(大文件)并且每天都在积累。 我想按文件大小轮换访问日志文件。

我试过了:

<Valve className="org.apache.catalina.valves.AccessLogValve"
         directory="${catalina.home}/../logs"  prefix="access_log." suffix=".txt"
         rotatable ="false"
         pattern="common" resolveHosts="false"/>

但它不适用于大小,它只生成一个文件并将所有日期的日志添加到同一文件中。 如何让它按日志文件的大小旋转?

【问题讨论】:

    标签: tomcat logging


    【解决方案1】:

    默认情况下,Tomcat 不支持按大小旋转文件,您可以自行修改$TOMCAT_HOME/conf/logging.properties。请参考How To Configure Apache Tomcat 6.0/7.0 or tc Server to rotate log files by size with logging.properties或其他文章。

    2017/8/30 更新

    解决方案是实现一个 Tomcat Valve 元素。以下是使用 java.util.logging API 编写访问日志的示例代码:

    package org.mylog;
    import java.io.CharArrayWriter;
    import java.io.IOException;
    import java.util.logging.*;
    
    public class CustomAccessLog extends org.apache.catalina.valves.AbstractAccessLogValve {
        public static class NoFormat extends Formatter {
            public synchronized String format(LogRecord record) {
                return record.getMessage();
            }   
        }
    
        private Logger log = Logger.getLogger("access_log");
        public CustomAccessLog() {
            log = Logger.getLogger("access_log");
            //not required, use the formatter that only print log message.
            Handler[] ha = log.getHandlers();
            for (int i = 0; i < ha.length; i++) {
                ha[i].setFormatter(new NoFormat());
            }
        }
        //@Override
        public void log(CharArrayWriter message) {
            log.info(message.append('\n').toString());
        }
    }
    

    将编译好的类打包到 jar 并复制到 %TOMCAT_HOME/lib

    修改%TOMCAT_HOME/conf/server.xml,替换

    跟一个

    修改 %TOMCAT_HOME/conf/logging.properties 为CustomAccessLog 添加日志配置。

    #Remember to add 9access.java.util.logging.FileHandler to "handlers"
    #for example:
    #handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler, 9access.java.util.logging.FileHandler
    9access.java.util.logging.FileHandler.level = FINE
    9access.java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
    9access.java.util.logging.FileHandler.pattern = ${catalina.base}/logs/access_log.%g.txt
    9access.java.util.logging.FileHandler.limit = 1000000
    9access.java.util.logging.FileHandler.count = 5
    access_log.level = FINE
    access_log.handlers = 9access.java.util.logging.FileHandler
    

    我在 Tomcat v8.5.20 中对其进行了测试,但它也适用于 6.x/7.x/8.x

    【讨论】:

    • 看完org.apache.catalina.valves.AccessLogValve的源码。访问日志不是通过日志 API 写入的,因此更改日志配置不起作用。请参考更新后的答案。
    • 感谢 beckyang。它正在工作。
    • @BeckYang 在你的回答中你已经定义了公共方法 AL。这是对的吗 ?因为我收到缺少返回类型的错误。
    • 它不适用于 tomcat 8.5.20。我不知道我的代码有什么问题。
    • @Hkachhia,我在 Tomcat v8.5.20 中测试后纠正了答案中的一些错误。如果Tomcat启动后%TOMCAT_HOME/logs/access_log.txt不存在,请验证9access.java.util.logging.FileHandler是否添加到%TOMCAT_HOME/conf/logging.properties中的handlers
    猜你喜欢
    • 2015-08-26
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 2010-09-19
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多