聊聊rocketmq的DailyRollingFileAppender

蚀纹组合
• 阅读 2064

本文主要研究一下rocketmq的DailyRollingFileAppender

DailyRollingFileAppender

org/apache/rocketmq/logging/inner/LoggingBuilder.java

   public static class DailyRollingFileAppender extends FileAppender {

        static final int TOP_OF_TROUBLE = -1;
        static final int TOP_OF_MINUTE = 0;
        static final int TOP_OF_HOUR = 1;
        static final int HALF_DAY = 2;
        static final int TOP_OF_DAY = 3;
        static final int TOP_OF_WEEK = 4;
        static final int TOP_OF_MONTH = 5;


        /**
         * The date pattern. By default, the pattern is set to
         * "'.'yyyy-MM-dd" meaning daily rollover.
         */
        private String datePattern = "'.'yyyy-MM-dd";

        private String scheduledFilename;

        private long nextCheck = System.currentTimeMillis() - 1;

        Date now = new Date();

        SimpleDateFormat sdf;

        RollingCalendar rc = new RollingCalendar();

        final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");


        public void setDatePattern(String pattern) {
            datePattern = pattern;
        }

        public String getDatePattern() {
            return datePattern;
        }

        public void activateOptions() {
            super.activateOptions();
            if (datePattern != null && fileName != null) {
                now.setTime(System.currentTimeMillis());
                sdf = new SimpleDateFormat(datePattern);
                int type = computeCheckPeriod();
                printPeriodicity(type);
                rc.setType(type);
                File file = new File(fileName);
                scheduledFilename = fileName + sdf.format(new Date(file.lastModified()));

            } else {
                SysLogger.error("Either File or DatePattern options are not set for appender [" + name + "].");
            }
        }

        void printPeriodicity(int type) {
            switch (type) {
                case TOP_OF_MINUTE:
                    SysLogger.debug("Appender [" + name + "] to be rolled every minute.");
                    break;
                case TOP_OF_HOUR:
                    SysLogger.debug("Appender [" + name + "] to be rolled on top of every hour.");
                    break;
                case HALF_DAY:
                    SysLogger.debug("Appender [" + name + "] to be rolled at midday and midnight.");
                    break;
                case TOP_OF_DAY:
                    SysLogger.debug("Appender [" + name + "] to be rolled at midnight.");
                    break;
                case TOP_OF_WEEK:
                    SysLogger.debug("Appender [" + name + "] to be rolled at start of week.");
                    break;
                case TOP_OF_MONTH:
                    SysLogger.debug("Appender [" + name + "] to be rolled at start of every month.");
                    break;
                default:
                    SysLogger.warn("Unknown periodicity for appender [" + name + "].");
            }
        }

        int computeCheckPeriod() {
            RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone, Locale.getDefault());
            // set sate to 1970-01-01 00:00:00 GMT
            Date epoch = new Date(0);
            if (datePattern != null) {
                for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
                    simpleDateFormat.setTimeZone(gmtTimeZone);
                    String r0 = simpleDateFormat.format(epoch);
                    rollingCalendar.setType(i);
                    Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));
                    String r1 = simpleDateFormat.format(next);
                    if (r0 != null && r1 != null && !r0.equals(r1)) {
                        return i;
                    }
                }
            }
            return TOP_OF_TROUBLE;
        }

        void rollOver() throws IOException {

            if (datePattern == null) {
                handleError("Missing DatePattern option in rollOver().");
                return;
            }

            String datedFilename = fileName + sdf.format(now);

            if (scheduledFilename.equals(datedFilename)) {
                return;
            }
            this.closeFile();

            File target = new File(scheduledFilename);
            if (target.exists() && !target.delete()) {
                SysLogger.error("Failed to delete [" + scheduledFilename + "].");
            }

            File file = new File(fileName);
            boolean result = file.renameTo(target);
            if (result) {
                SysLogger.debug(fileName + " -> " + scheduledFilename);
            } else {
                SysLogger.error("Failed to rename [" + fileName + "] to [" + scheduledFilename + "].");
            }

            try {
                this.setFile(fileName, true, this.bufferedIO, this.bufferSize);
            } catch (IOException e) {
                handleError("setFile(" + fileName + ", true) call failed.");
            }
            scheduledFilename = datedFilename;
        }

        protected void subAppend(LoggingEvent event) {
            long n = System.currentTimeMillis();
            if (n >= nextCheck) {
                now.setTime(n);
                nextCheck = rc.getNextCheckMillis(now);
                try {
                    rollOver();
                } catch (IOException ioe) {
                    if (ioe instanceof InterruptedIOException) {
                        Thread.currentThread().interrupt();
                    }
                    SysLogger.error("rollOver() failed.", ioe);
                }
            }
            super.subAppend(event);
        }
    }
  • 这里重写了subAppend方法,先检查当前时间是否大于nextCheck值,大于则更新nextCheck值,然后进行rollOver操作,最后在调用父类的subAppend方法
  • rollOver方法先检查datedFilename是否等于scheduledFilename,如果不等则进行重命名操作,然后调用FileAppender的setFile操作,最后更新scheduledFilename值

小结

  • rocketmq的DailyRollingFileAppender的实现是重写subAppend,每次subAppend之前先检查是否需要重命名文件,如果需要则调用rollOver方法
  • rollOver方法主要是将文件名重名为scheduledFilename,datePattern的格式为.yyyy-MM-dd

doc

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Stella981 Stella981
4年前
RocketMQ 平滑升级到主从切换(实战篇)
本文主要介绍如何将RocketMQ集群从原先的主从同步升级到主从切换。本文首先介绍与DLedger多副本即RocketMQ主从切换相关的核心配置属性,然后尝试搭建一个主从同步集群,最后将原先的RocketMQ集群平滑升级到DLedger集群的示例,并简单测试一下主从切换功能。1、RocketMQ主从切换核心配置参数详解
Stella981 Stella981
4年前
SpringBoot 整合 RocketMq
1、安装RocketMqdockersearchrocketmqdockerpullrocketmqinc/rocketmq:4.4.0建立nameserverdockerrundp9876:9876v/data/rocketmq/namesrv/
Stella981 Stella981
4年前
RocketMQ 平滑升级到主从切换(实战篇)
本文主要介绍如何将RocketMQ集群从原先的主从同步升级到主从切换。首先先介绍与DLedger多副本即RocketMQ主从切换相关的核心配置属性,然后尝试搭建一个主从同步集群,再从原先的RocketMQ集群平滑升级到DLedger集群的示例,并简单测试一下主从切换功能。1、RocketMQDLedger多副本即主从切换核心配
Stella981 Stella981
4年前
Linux安装RocketMQ
本文介绍Linux安装RocketMQ。1.RocketMQ简介RocketMQ是阿里巴巴中间件开发的分布式消息系统,曾经经历过很多阿里巴巴大型项目的实际检验。在去年已经正式捐献给Apache开源基金会,成为孵化项目。今年正式升级成为了apache的顶级项目。RocketMQ官网地址为:http://rocketm
Wesley13 Wesley13
4年前
Java9之后的模块化烦恼解决(由RocketMQ升级OpenJDK11想到的)
本文基于OpenJDK11最近从OpenJDK8升级到了OpenJDK11,系统业务MQ用的RocketMQ,升级RocketMQ过程中,在已修改好JVM参数的情况下(参考我另一篇文章),遇到如下异常:java.lang.IllegalStateException:java.lang.reflect.InaccessibleObject
Stella981 Stella981
4年前
RocketMQ进阶
!(https://oscimg.oschina.net/oscnet/6f347d08dcb54249888c46653945b350.png)分布式消息选型的时候是否支持事务消息是一个很重要的考量点,而目前只有RocketMQ对事务消息支持的最好。今天我们来唠唠如何实现RocketMQ的事务消息!ApacheRocketMQ
Stella981 Stella981
4年前
Linux的centos7.2部署rocketMq3.5.8
背景最近公司的终端机需要接通推送,然后查看对比了一下,觉得rocketMq更合适一点,所以选择了rocketMq进行测试。软件清单a、git(yumintsallgit);b、jdk1.8;c、maven;d、rocketmq操作步骤1、首先下载rocketMq3.5.82、tarzxvfroc
Stella981 Stella981
4年前
RocketMQ 升级到主从切换(DLedger、多副本)实战
本文主要介绍如何将RocketMQ集群从原先的主从同步升级到主从切换。首先先介绍与DLedger多副本即RocketMQ主从切换相关的核心配置属性,然后尝试搭建一个主从同步集群,再从原先的RocketMQ集群平滑升级到DLedger集群的示例,并简单测试一下主从切换功能。1、RocketMQDLedger多副本即主从切换核心配
Stella981 Stella981
4年前
RocketMQ消息轨迹
RocketMQ消息轨迹主要包含两篇文章:设计篇与源码分析篇,本节将详细介绍RocketMQ消息轨迹设计相关。RocketMQ消息轨迹,主要跟踪消息发送、消息消费的轨迹,即详细记录消息各个处理环节的日志,从设计上至少需要解决如下三个核心问题:消费轨迹数据格式记录消息轨迹(消息日志)消息轨迹数据存储在哪?1、消息轨迹数
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
蚀纹组合
蚀纹组合
Lv1
路逐山光何处尽,春随草色向南深。
文章
3
粉丝
0
获赞
0