前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊rocketmq的RollingFileAppender

聊聊rocketmq的RollingFileAppender

作者头像
code4it
发布2018-09-17 17:16:20
4300
发布2018-09-17 17:16:20
举报

本文主要研究一下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

  • LoggingBuilder
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RollingFileAppender
  • RollingFileAppender.rollOver
  • 小结
  • doc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档