版本要求如下:

版本 8.5.x,需要 8.5.16 以上
版本 8.0.x,需要 8.0.45 以上
版本 7.0.x,需要 7.0.79 以上

1. 对于默认的日志(Catalina log)配置:

修改conf/logging.properties文件,添加maxDays关键字来指定日志保留的最大天数。

配置前:

1catalina.org.apache.juli.FileHandler.level = FINE
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.

配置后:

1catalina.org.apache.juli.FileHandler.level = FINE
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.
1catalina.org.apache.juli.FileHandler.maxDays = 14

2. 对于访问日志(Access log)的配置:

修改conf/server.xml文件,对org.apache.catalina.valves.AccessLogValve字段添加maxDays属性来指定日志保留的最大天数。

配置前:

        <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" />

配置后:

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

3. 相关说明

由于tomcat中对于日志的记录分为两种,一种是普通的日志记录,通过使用conf/logging.properties配置文件进行配置,配置文件中也指定了不同的日志所使用的日志记录器和相关配置参数。
举例如下:

handlers = 1catalina.org.apache.juli.FileHandler, \
           2localhost.org.apache.juli.FileHandler, \
           3manager.org.apache.juli.FileHandler, \
           java.util.logging.ConsoleHandler

.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################

1catalina.org.apache.juli.FileHandler.level = FINE
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.
1catalina.org.apache.juli.FileHandler.maxDays = 90
1catalina.org.apache.juli.FileHandler.encoding = UTF-8

2localhost.org.apache.juli.FileHandler.level = FINE
2localhost.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
2localhost.org.apache.juli.FileHandler.prefix = localhost.
2localhost.org.apache.juli.FileHandler.maxDays = 90
2localhost.org.apache.juli.FileHandler.encoding = UTF-8

3manager.org.apache.juli.FileHandler.level = FINE
3manager.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
3manager.org.apache.juli.FileHandler.prefix = manager.
3manager.org.apache.juli.FileHandler.bufferSize = 16384
3manager.org.apache.juli.FileHandler.maxDays = 90
3manager.org.apache.juli.FileHandler.encoding = UTF-8

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.encoding = UTF-8

############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = \
   2localhost.org.apache.juli.FileHandler

org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = \
   3manager.org.apache.juli.FileHandler

# For example, set the org.apache.catalina.util.LifecycleBase logger to log
# each component that extends LifecycleBase changing state:
#org.apache.catalina.util.LifecycleBase.level = FINE

其中定义了catalinalocalhostmanager三种日志的记录方式。这三种都是在这里配置的。

另外一种是访问日志,访问日志参考官方文档中的说法,因为要处理大量流式数据,还要高效运行,所以实现方式和普通的业务日志记录不太一样,具体的说明(官方文档7.0.107)如下:

  • Access logging is a related but different feature, which is implemented as a Valve. It uses self-contained logic to write its log files. The essential requirement for access logging is to handle a large continuous stream of data with low overhead, so it only uses Apache Commons Logging for its own debug messages. This implementation approach avoids additional overhead and potentially complex configuration. Please refer to the Valves documentation for more details on its configuration, including the various report formats.

其中说明了让我们参考Value文档,这个里面说明了如何配置属性,指定访问日志的最大保存天数。摘抄如下:

Attribute Description
maxDays The maximum number of days rotated access logs will be retained for before being deleted. If not specified, the default value of -1 will be used which means never delete old files.

进一步观察xml配置文件中,访问日志是配置到org.apache.catalina.valves.AccessLogValve这个类中进行实现的,下载tomcat7.0.107源码后,打开该文件找到如下代码:

...
955 		/**
956 		 * Execute a periodic task, such as reloading, etc. This method will be
957 		 * invoked inside the classloading context of this container. Unexpected
958 		 * throwables will be caught and logged.
959 		 */
960 		@Override
961 		public synchronized void backgroundProcess() {
962 			if (getState().isAvailable() && getEnabled() && writer != null &&
963 					buffered) {
964 				writer.flush();
965 			}
966             // 这里使用了maxDays作为判定依据
967 			int maxDays = this.maxDays;
968 			String prefix = this.prefix;
969 			String suffix = this.suffix;
970             // 检查三个变量,来决定是否需要进行日志文件处理
971 			if (rotatable && checkForOldLogs && maxDays > 0) {
972 				long deleteIfLastModifiedBefore =
973 						System.currentTimeMillis() - (maxDays * 24L * 60 * 60 * 1000);
974 				File dir = getDirectoryFile();
975 				if (dir.isDirectory()) {
976 					String[] oldAccessLogs = dir.list();
977 
978 					if (oldAccessLogs != null) {
979 						for (String oldAccessLog : oldAccessLogs) {
980 							boolean match = false;
981 
982 							if (prefix != null && prefix.length() > 0) {
983 								if (!oldAccessLog.startsWith(prefix)) {
984 									continue;
985 								}
986 								match = true;
987 							}
988 
989 							if (suffix != null && suffix.length() > 0) {
990 								if (!oldAccessLog.endsWith(suffix)) {
991 									continue;
992 								}
993 								match = true;
994 							}
995 
996 							if (match) {
997 								File file = new File(dir, oldAccessLog);
998 								if (file.isFile() && file.lastModified() < deleteIfLastModifiedBefore) { // 通过判断文件的最后修改时间
999 									if (!file.delete()) {
1000										log.warn(sm.getString(
1001												"accessLogValve.deleteFail", file.getAbsolutePath()));
1002									}
1003								}
1004							}
1005						}
1006					}
1007				}
1008				checkForOldLogs = false;
1009			}
1010		}
...
1258		/**
1259		 * Open the new log file for the date specified by <code>dateStamp</code>.
1260		 */
1261		protected synchronized void open() {
1262			// Open the current log file
1263			// If no rotate - no need for dateStamp in fileName
1264			File pathname = getLogFile(rotatable && !renameOnRotate);
1265
1266			Charset charset = null;
1267			if (encoding != null) {
1268				try {
1269					charset = B2CConverter.getCharset(encoding);
1270				} catch (UnsupportedEncodingException ex) {
1271					log.error(sm.getString(
1272							"accessLogValve.unsupportedEncoding", encoding), ex);
1273				}
1274			}
1275			if (charset == null) {
1276				charset = Charset.defaultCharset();
1277			}
1278
1279			try {
1280				writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
1281						new FileOutputStream(pathname, true), charset), 128000),
1282						false);
1283
1284				currentLogFile = pathname;
1285			} catch (IOException e) {
1286				writer = null;
1287				currentLogFile = null;
1288				log.error(sm.getString("accessLogValve.openFail", pathname), e);
1289			}
1290			// Rotating a log file will always trigger a new file to be opened so
1291			// when a new file is opened, check to see if any old files need to be
1292			// removed.
1293			checkForOldLogs = true;
1294		}

这个方法作为一个后台任务,会通过tomcat中的线程定时调用,然后每次创建新的日志文件的时候,会将checkForOldLogs变量置为true,然后调用backgroundProcess方法的时候,就会自动进行旧文件检查和清理了。

文中内容可以参考以下两个链接:

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐