tomcat配置Catalina.out日志和access访问日志滚动和最大保存天数
tomcat日志,Catalina日志和access访问日志配置按天数滚动并且指定最大保存天数的配置方式,简单分析访问日志进行清理的实现机制。
版本要求如下:
版本 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 "%r" %s %b" />
配置后:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt" maxDays="7"
pattern="%h %l %u %t "%r" %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
其中定义了catalina
,localhost
,manager
三种日志的记录方式。这三种都是在这里配置的。
另外一种是访问日志,访问日志参考官方文档中的说法,因为要处理大量流式数据,还要高效运行,所以实现方式和普通的业务日志记录不太一样,具体的说明(官方文档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
方法的时候,就会自动进行旧文件检查和清理了。
文中内容可以参考以下两个链接:
更多推荐
所有评论(0)