聊聊rocketmq的RollingFileAppender
序
本文主要研究一下rocketmq的RollingFileAppender
RollingFileAppender
org/apache/rocketmq/logging/inner/LoggingBuilder.java
public static class RollingFileAppender extends FileAppender { protected long maxFileSize = 10 * 1024 * 1024; protected int maxBackupIndex = 1; private long nextRollover = 0; public RollingFileAppender() { super(); } public int getMaxBackupIndex() { return maxBackupIndex; } public long getMaximumFileSize() { return maxFileSize; } //...... public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize) throws IOException { super.setFile(fileName, append, this.bufferedIO, this.bufferSize); if (append) { File f = new File(fileName); ((CountingQuietWriter) qw).setCount(f.length()); } } public void setMaxBackupIndex(int maxBackups) { this.maxBackupIndex = maxBackups; } public void setMaximumFileSize(long maxFileSize) { this.maxFileSize = maxFileSize; } protected void setQWForFiles(Writer writer) { this.qw = new CountingQuietWriter(writer, this); } protected void subAppend(LoggingEvent event) { super.subAppend(event); if (fileName != null && qw != null) { long size = ((CountingQuietWriter) qw).getCount(); if (size >= maxFileSize && size >= nextRollover) { rollOver(); } } } protected class CountingQuietWriter extends QuietWriter { protected long count; public CountingQuietWriter(Writer writer, Appender appender) { super(writer, appender); } public void write(String string) { try { out.write(string); count += string.length(); } catch (IOException e) { appender.handleError("Write failure.", e, Appender.CODE_WRITE_FAILURE); } } public long getCount() { return count; } public void setCount(long count) { this.count = count; } } }
- 这里重写了subAppend方法,调用父类subAppend方法之后,判断是否需要rollOver
- 这里定义了maxFileSize,即单个文件的大小,然后还定义了nextRollover索引
- 这里使用的是CountingQuietWriter,里头有个count来累积计算字符串的长度
RollingFileAppender.rollOver
org/apache/rocketmq/logging/inner/LoggingBuilder.java
public void rollOver() { File target; File file; if (qw != null) { long size = ((CountingQuietWriter) qw).getCount(); SysLogger.debug("rolling over count=" + size); nextRollover = size + maxFileSize; } SysLogger.debug("maxBackupIndex=" + maxBackupIndex); boolean renameSucceeded = true; if (maxBackupIndex > 0) { file = new File(fileName + '.' + maxBackupIndex); if (file.exists()) { renameSucceeded = file.delete(); } for (int i = maxBackupIndex - 1; i >= 1 && renameSucceeded; i--) { file = new File(fileName + "." + i); if (file.exists()) { target = new File(fileName + '.' + (i + 1)); SysLogger.debug("Renaming file " + file + " to " + target); renameSucceeded = file.renameTo(target); } } if (renameSucceeded) { target = new File(fileName + "." + 1); this.closeFile(); // keep windows happy. file = new File(fileName); SysLogger.debug("Renaming file " + file + " to " + target); renameSucceeded = file.renameTo(target); if (!renameSucceeded) { try { this.setFile(fileName, true, bufferedIO, bufferSize); } catch (IOException e) { if (e instanceof InterruptedIOException) { Thread.currentThread().interrupt(); } SysLogger.error("setFile(" + fileName + ", true) call failed.", e); } } } } if (renameSucceeded) { try { this.setFile(fileName, false, bufferedIO, bufferSize); nextRollover = 0; } catch (IOException e) { if (e instanceof InterruptedIOException) { Thread.currentThread().interrupt(); } SysLogger.error("setFile(" + fileName + ", false) call failed.", e); } } }
- 这个方法首先更新nextRollover的值,然后根据maxBackupIndex来递增重命名文件,然后再把现有的文件重名为为.1后缀
- 重命名成功之后,再对新的文件进行setFile相关设置,关联writer,写入header
小结
RollingFileAppender在每次append的时候,都会先append数据,然后再判断是否超出文件大小限制,超出了再执行rollOver操作,对既有文件进行重命名,然后重新生成新的文件。注意这里没有进行同步操作,因此需要最外层调用的方法有同步并发控制。
doc
相关推荐
IT农场 2020-11-13
LCFlxfldy 2020-08-17
ljcsdn 2020-07-27
LCFlxfldy 2020-07-05
lypgcs 2020-06-27
陈晨软件五千言 2020-06-17
qingyuerji 2020-06-14
MojitoBlogs 2020-06-14
lypgcs 2020-06-14
陈晨软件五千言 2020-06-14
meilongwhpu 2020-06-13
陈晨软件五千言 2020-06-11
qingyuerji 2020-06-09
MojitoBlogs 2020-06-09
meilongwhpu 2020-06-08
meilongwhpu 2020-06-08
lypgcs 2020-06-07
MojitoBlogs 2020-06-04
meilongwhpu 2020-05-30