zoukankan      html  css  js  c++  java
  • how tomcat works读书笔记 七 日志记录器

    大家能够松一口气了,这个组件比較简单,这一节和前面几节想比,也简单的多。



    Logger接口

    Tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口。

    package org.apache.catalina;
    
    import java.beans.PropertyChangeListener;
    
    public interface Logger {
        
        public static final int FATAL = Integer.MIN_VALUE;
        public static final int ERROR = 1;
        public static final int WARNING = 2;
        public static final int INFORMATION = 3;
        public static final int DEBUG = 4;
    
        public Container getContainer();
        public void setContainer(Container container);
        public String getInfo();
        public int getVerbosity();
        public void setVerbosity(int verbosity);
        public void addPropertyChangeListener(PropertyChangeListener listener);
    
        public void log(String message);
        public void log(Exception exception, String msg);
        public void log(String message, Throwable throwable);
        public void log(String message, int verbosity);
        public void log(String message, Throwable throwable, int verbosity);
        public void removePropertyChangeListener(PropertyChangeListener listener);
    }


    Logger定义了五种日志记录基本,当我们在调用log(String message, int verbosity)方法记录日志的时候,仅仅有传进来的verbosity小于等于系统的默认值才会记录。话说大家知道Integer.MIN_VALUE等于多少吗?大概负的21亿左右吧。setVerbosity与getVerbosity是干什么的还须要我说么?

    Tomcat的日志记录器


    LoggerBase类(抽象类)

    它实现了Logger接口中除log(String message)方法外的其余方法;
    在类中默认了日志记录级别为
             protected int verbosity = ERROR;
    可是我们能够通过setVerbosity(int verbosity)来又一次设置记录级别;
    看看定义的接受日志级别的两个log方法
    public void log(String message, int verbosity) {
        if (this.verbosity >= verbosity)
            log(message);
    }
    public void log(String message, Throwable throwable, int verbosity) {
        if (this.verbosity >= verbosity)
            log(message, throwable);
    }

    SystemOutLogger类

    看名字就知道,信息最后输出到控制台。

    SysteErrLogger类

    看名字就知道,它是错误输出,信息仍在控制台,只是是红色的。

    FileLogger类

    看名字就知道,它是吧信息输出的文件中。
    只是详细的来说,里面还是有点说头的,慢慢来。


    首先FileLogger还实现了Lifecycle接口,因此它能够像其它组件一样被父组件所启动。
    在本节中FileLogger的start与stop方法事实上仅仅是改变了布尔值started而已,没有做其它的,还有一方面,FileLogger的start与stop方法也并没有被调用!
    如今我们就看看怎么给文件中写信息。


     

    public void log(String msg) {
    
            // Construct the timestamp we will use, if requested
            Timestamp ts = new Timestamp(System.currentTimeMillis());
            String tsString = ts.toString().substring(0, 19);
            String tsDate = tsString.substring(0, 10);
            System.out.println("tsString   "+tsString); //tsString   2014-10-20 15:25:27
            System.out.println("ts   "+ts);            //ts   2014-10-20 15:25:27.406
            System.out.println("tsDate   "+tsDate);        //tsDate   2014-10-20
    
            // If the date has changed, switch log files
            if (!date.equals(tsDate)) {
                synchronized (this) {
                    if (!date.equals(tsDate)) {
                        close();
                        date = tsDate;
                        open();
                    }
                }
            }
    
            // Log this message, timestamped if necessary
            if (writer != null) {
                if (timestamp) {
                    writer.println(tsString + " " + msg);
                } else {
                    writer.println(msg);
                }
            }
        }


    File默认是每一天一个新的文件,文件内格式就是日期+详细信息(假设timestamp为true的话);
    那close(),open()方法和writer属性又是什么呢?
     
       private void open() {
    
            // Create the directory if necessary
            File dir = new File(directory);
            if (!dir.isAbsolute())
                dir = new File(System.getProperty("catalina.base"), directory);  //至于catalina.base是什么 一会再说
            dir.mkdirs();
    
            // Open the current log file
            try {
                String pathname = dir.getAbsolutePath() + File.separator +
                    prefix + date + suffix;
                writer = new PrintWriter(new FileWriter(pathname, true), true);
            } catch (IOException e) {
                writer = null;
            }
    
        }

    先检查给定的文件夹是否存在,假设不存在新建一个;接着依据前缀,时间,后缀设定文件名称;依据文件名称填充writer对象。


        private void close() {
    
            if (writer == null)
                return;
            writer.flush();
            writer.close();
            writer = null;
            date = "";
        }

    FileLogger中的date代表的就是当前的时间,当然关闭后为空。

    应用程序


    Bootstrap类

    ...
        System.setProperty("catalina.base", System.getProperty("user.dir"));
        FileLogger logger = new FileLogger();
        logger.setPrefix("FileLog_");
        logger.setSuffix(".txt");
        logger.setTimestamp(true);
        logger.setDirectory("webroot");
        context.setLogger(logger);
    ....

    SimpleContext类

    public synchronized void start() throws LifecycleException {
        log("starting Context");
        ........
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
        log("Context started");
      }
    private void log(String message) {
        Logger logger = this.getLogger();
        if (logger!=null)
          logger.log(message);
      }



    执行后在项目的webroot文件夹下就能够看到FileLog_2014-10-20.txt文件;
    每次执行,在文件里都会多出例如以下的内容
    2014-10-20 14:34:21 HttpConnector Opening server socket on all host IP addresses
    2014-10-20 14:34:22 HttpConnector[8080] Starting background thread
    2014-10-20 14:34:22 HttpProcessor[8080][0] Starting background thread
    2014-10-20 14:34:22 HttpProcessor[8080][1] Starting background thread
    2014-10-20 14:34:22 HttpProcessor[8080][2] Starting background thread
    2014-10-20 14:34:22 HttpProcessor[8080][3] Starting background thread
    2014-10-20 14:34:22 HttpProcessor[8080][4] Starting background thread
    2014-10-20 14:34:22 starting Context
    2014-10-20 14:34:22 Context started
  • 相关阅读:
    【前端】Vue2全家桶案例《看漫画》之五、引入axios
    【前端】Vue2全家桶案例《看漫画》之四、漫画页
    【前端】Vue2全家桶案例《看漫画》之三、引入vuex
    【前端】Vue2全家桶案例《看漫画》之番外篇、express上传漫画(可选)
    【前端】Vue2全家桶案例《看漫画》之二、完成首页基本样式
    【前端】Vue2全家桶案例《看漫画》之一、添加四个导航页
    【前端】Vue和Vux开发WebApp日志四、增加命令行参数
    【前端】Vue和Vux开发WebApp日志三、完善gulp任务
    [TabControl] TabControl控件的最佳实践,可以把一个窗体和用户控件添加进来
    一步一步玩控件:自定义TabControl——从山寨Safari开始
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/7066940.html
Copyright © 2011-2022 走看看