博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊rocketmq的FileAppender
阅读量:6300 次
发布时间:2019-06-22

本文共 9334 字,大约阅读时间需要 31 分钟。

本文主要研究一下rocketmq的FileAppender

WriterAppender

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

public static class WriterAppender extends Appender {        protected boolean immediateFlush = true;        protected String encoding;        protected QuietWriter qw;        public WriterAppender() {        }        public void setImmediateFlush(boolean value) {            immediateFlush = value;        }        public boolean getImmediateFlush() {            return immediateFlush;        }        public void activateOptions() {        }        public void append(LoggingEvent event) {            if (!checkEntryConditions()) {                return;            }            subAppend(event);        }        protected boolean checkEntryConditions() {            if (this.closed) {                SysLogger.warn("Not allowed to write to a closed appender.");                return false;            }            if (this.qw == null) {                handleError("No output stream or file set for the appender named [" +                    name + "].");                return false;            }            if (this.layout == null) {                handleError("No layout set for the appender named [" + name + "].");                return false;            }            return true;        }        public synchronized void close() {            if (this.closed) {                return;            }            this.closed = true;            writeFooter();            reset();        }        protected void closeWriter() {            if (qw != null) {                try {                    qw.close();                } catch (IOException e) {                    handleError("Could not close " + qw, e, CODE_CLOSE_FAILURE);                }            }        }        protected OutputStreamWriter createWriter(OutputStream os) {            OutputStreamWriter retval = null;            String enc = getEncoding();            if (enc != null) {                try {                    retval = new OutputStreamWriter(os, enc);                } catch (IOException e) {                    SysLogger.warn("Error initializing output writer.");                    SysLogger.warn("Unsupported encoding?");                }            }            if (retval == null) {                retval = new OutputStreamWriter(os);            }            return retval;        }        public String getEncoding() {            return encoding;        }        public void setEncoding(String value) {            encoding = value;        }        public synchronized void setWriter(Writer writer) {            reset();            this.qw = new QuietWriter(writer, this);            writeHeader();        }        protected void subAppend(LoggingEvent event) {            this.qw.write(this.layout.format(event));            if (layout.ignoresThrowable()) {                String[] s = event.getThrowableStr();                if (s != null) {                    for (String s1 : s) {                        this.qw.write(s1);                        this.qw.write(LINE_SEP);                    }                }            }            if (shouldFlush(event)) {                this.qw.flush();            }        }        protected void reset() {            closeWriter();            this.qw = null;        }        protected void writeFooter() {            if (layout != null) {                String f = layout.getFooter();                if (f != null && this.qw != null) {                    this.qw.write(f);                    this.qw.flush();                }            }        }        protected void writeHeader() {            if (layout != null) {                String h = layout.getHeader();                if (h != null && this.qw != null) {                    this.qw.write(h);                }            }        }        protected boolean shouldFlush(final LoggingEvent event) {            return event != null && immediateFlush;        }    }复制代码
  • 这个接口定义了writeHeader、writeFooter、append等方法
  • append方法这里参数是LoggingEvent,内部委托给subAppend
  • subAppend方法调用layout进行格式化event,然后如果需要flush,则会直接对qw进行flush

FileAppender

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

public static class FileAppender extends WriterAppender {        protected boolean fileAppend = true;        protected String fileName = null;        protected boolean bufferedIO = false;        protected int bufferSize = 8 * 1024;        public FileAppender() {        }        public FileAppender(Layout layout, String filename, boolean append)            throws IOException {            this.layout = layout;            this.setFile(filename, append, false, bufferSize);        }        public void setFile(String file) {            fileName = file.trim();        }        public boolean getAppend() {            return fileAppend;        }        public String getFile() {            return fileName;        }        public void activateOptions() {            if (fileName != null) {                try {                    setFile(fileName, fileAppend, bufferedIO, bufferSize);                } catch (IOException e) {                    handleError("setFile(" + fileName + "," + fileAppend + ") call failed.",                        e, CODE_FILE_OPEN_FAILURE);                }            } else {                SysLogger.warn("File option not set for appender [" + name + "].");                SysLogger.warn("Are you using FileAppender instead of ConsoleAppender?");            }        }        protected void closeFile() {            if (this.qw != null) {                try {                    this.qw.close();                } catch (IOException e) {                    if (e instanceof InterruptedIOException) {                        Thread.currentThread().interrupt();                    }                    SysLogger.error("Could not close " + qw, e);                }            }        }        public boolean getBufferedIO() {            return this.bufferedIO;        }        public int getBufferSize() {            return this.bufferSize;        }        public void setAppend(boolean flag) {            fileAppend = flag;        }        public void setBufferedIO(boolean bufferedIO) {            this.bufferedIO = bufferedIO;            if (bufferedIO) {                immediateFlush = false;            }        }        public void setBufferSize(int bufferSize) {            this.bufferSize = bufferSize;        }        public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)            throws IOException {            SysLogger.debug("setFile called: " + fileName + ", " + append);            if (bufferedIO) {                setImmediateFlush(false);            }            reset();            FileOutputStream ostream;            try {                ostream = new FileOutputStream(fileName, append);            } catch (FileNotFoundException ex) {                String parentName = new File(fileName).getParent();                if (parentName != null) {                    File parentDir = new File(parentName);                    if (!parentDir.exists() && parentDir.mkdirs()) {                        ostream = new FileOutputStream(fileName, append);                    } else {                        throw ex;                    }                } else {                    throw ex;                }            }            Writer fw = createWriter(ostream);            if (bufferedIO) {                fw = new BufferedWriter(fw, bufferSize);            }            this.setQWForFiles(fw);            this.fileName = fileName;            this.fileAppend = append;            this.bufferedIO = bufferedIO;            this.bufferSize = bufferSize;            writeHeader();            SysLogger.debug("setFile ended");        }        protected void setQWForFiles(Writer writer) {            this.qw = new QuietWriter(writer, this);        }        protected void reset() {            closeFile();            this.fileName = null;            super.reset();        }    }复制代码
  • 写文件,这里定义了bufferSize为8 * 1024,如果开启bufferedIO,则创建的是BufferedWriter
  • setQWForFiles方法根据指定的writer创建了QuietWriter
  • setFile方法设置了qw之后,就直接writeHeader

QuietWriter

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

private static class QuietWriter extends FilterWriter {        protected Appender appender;        public QuietWriter(Writer writer, Appender appender) {            super(writer);            this.appender = appender;        }        public void write(String string) {            if (string != null) {                try {                    out.write(string);                } catch (Exception e) {                    appender.handleError("Failed to write [" + string + "].", e,                        Appender.CODE_WRITE_FAILURE);                }            }        }        public void flush() {            try {                out.flush();            } catch (Exception e) {                appender.handleError("Failed to flush writer,", e,                    Appender.CODE_FLUSH_FAILURE);            }        }    }复制代码
  • QuietWriter继承自jdk的FilterWriter,实现了write(String)方法,重写了flush方法
  • FilterWriter实现了write(int c),write(char cbuf[], int off, int len),write(String str, int off, int len)方法,用于对字符串进行过滤

小结

rocketmq的FileAppender继承自WriterAppender,采取的是根据layout对LoggingEvent来格式化,然后写入QuietWriter,最后写入到文件。

doc

转载地址:http://ukwxa.baihongyu.com/

你可能感兴趣的文章
awk的数组
查看>>
我的友情链接
查看>>
这是我看过进程与线程定义解释最通俗易懂的
查看>>
centos 6.5上ansible初探
查看>>
linux下的简单网卡流量监控工具vnstat
查看>>
android内部存储
查看>>
微信公众平台api的Java调用
查看>>
CentOS服务器ntpdate同步
查看>>
Buffer类处理二进制
查看>>
人-标签-人
查看>>
JDK 64 位 或自定义jre 用exe4j 打包 exe 注意事项
查看>>
局域网内MAC Book连接Windows共享文件夹
查看>>
新一代 CI 持续集成工具 flow.ci 正式开源
查看>>
struts2.xml 文件中元素的排序
查看>>
Red hat Linux 系统管理篇 3
查看>>
JSP 页面通过 ognl 标签遍历集合中的所有内容
查看>>
观察者模式以及tomcat实现的观察者模式
查看>>
获取屏幕宽高
查看>>
我的友情链接
查看>>
android拍照并给照片添加备注,以GridView显示
查看>>