我是靠谱客的博主 可耐萝莉,这篇文章主要介绍servlet解析演进(5)-添加日志,现在分享给大家,希望可以做个参考。

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

每一个servlet容器都需要去定位问题,那日志肯定是必不可少的。我们平时启动系统的时候发现日志一直在打印一些信息,信息或是来自容器系统中,或是来自我们的应用系统。下面介绍简单的文件日志系统搭建。

日志文件搭建主要包含以下几个部分:

1、日志文件搭建

2、将日志文件配置到容器中。

3、连接器获得容器的logger实例写信息

4、HttpProcessor通过连接器获得容器的logger实例写信息

1、日志文件搭建:

日志文件的接口关系如图:

180754_ueap_166980.png

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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); //给servlet日志文件写特殊的信息,通常是一个环境日志。servlet日志的名字和类型对于容器来说是指定的具体的。该种类的信息被无条件的被记录。     public void log(String message); //写错误信息给servlet日志文件。该方法的实现最终由log(msg, exception)实现     public void log(Exception exception, String msg); //为servlet日志文件写入异常信息和堆栈信息     public void log(String message, Throwable throwable); //为servlet日志文件写入特定信息,通常是事件日志,记录日志等级比verbosity设置的高或者相等的信息。  public void log(String message, int verbosity);     public void log(String message, Throwable throwable, int verbosity); //删除属性变更监听器     public void removePropertyChangeListener(PropertyChangeListener listener); } ------------------------------
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package org.apache.catalina.logger; import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeListener; import java.io.CharArrayWriter; import java.io.PrintWriter; import javax.servlet.ServletException; import org.apache.catalina.Container; import org.apache.catalina.LifecycleException; import org.apache.catalina.Logger; public abstract class LoggerBase     implements Logger {    //与日志关联的容器     protected Container container = null; //debug等级     protected int debug = 0;     //包描述信息     protected static final String info =         "org.apache.catalina.logger.LoggerBase/1.0"; //容器的属性变更support实例        protected PropertyChangeSupport support = new PropertyChangeSupport(this);     //日志信息过滤级别,高于该级别的信息被记录下来         protected int verbosity = ERROR;     public Container getContainer() {         return (container);     } //容器设置     public void setContainer(Container container) {         Container oldContainer = this.container;         this.container = container;         support.firePropertyChange("container", oldContainer, this.container);     } //返回容器debugging详细级别。          public int getDebug() {         return (this.debug);     }     public void setDebug(int debug) {         this.debug = debug;     }     public String getInfo() {         return (info);     }     public int getVerbosity() {         return (this.verbosity);     }     public void setVerbosity(int verbosity) {         this.verbosity = verbosity;     }     public void setVerbosityLevel(String verbosity) {         if ("FATAL".equalsIgnoreCase(verbosity))             this.verbosity = FATAL;         else if ("ERROR".equalsIgnoreCase(verbosity))             this.verbosity = ERROR;         else if ("WARNING".equalsIgnoreCase(verbosity))             this.verbosity = WARNING;         else if ("INFORMATION".equalsIgnoreCase(verbosity))             this.verbosity = INFORMATION;         else if ("DEBUG".equalsIgnoreCase(verbosity))             this.verbosity = DEBUG;     }     public void addPropertyChangeListener(PropertyChangeListener listener) {         support.addPropertyChangeListener(listener);     } //抽象方法 具体的日志系统去实现     public abstract void log(String msg);     public void log(Exception exception, String msg) {         log(msg, exception);     } //打印出错servlet的堆栈信息         public void log(String msg, Throwable throwable) {         CharArrayWriter buf = new CharArrayWriter();         PrintWriter writer = new PrintWriter(buf);         writer.println(msg);         throwable.printStackTrace(writer);         Throwable rootCause = null;         if (throwable instanceof LifecycleException)             rootCause = ((LifecycleException) throwable).getThrowable();         else if (throwable instanceof ServletException)             rootCause = ((ServletException) throwable).getRootCause();         if (rootCause != null) {             writer.println("----- Root Cause -----");             rootCause.printStackTrace(writer);         }         log(buf.toString());     } //高于verbosity的信息被写打印出来     public void log(String message, int verbosity) {         if (this.verbosity >= verbosity)             log(message);     } //高于verbosity的错误信息被写打印出来     public void log(String message, Throwable throwable, int verbosity) {         if (this.verbosity >= verbosity)             log(message, throwable);     } //删除属性变更监听器     public void removePropertyChangeListener(PropertyChangeListener listener) {         support.removePropertyChangeListener(listener);     } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
文件日志 public class FileLogger     extends LoggerBase     implements Lifecycle { //日期字段     private String date = "";     /**      * 目录字段      */     private String directory = "logs";     /**      * 文件名称/版本号信息,即该日志实现的详细信息      */     protected static final String info =         "org.apache.catalina.logger.FileLogger/1.0";     /**      * 观察者      */     protected LifecycleSupport lifecycle = new LifecycleSupport(this);     /**      * 日志前缀      */     private String prefix = "catalina.";     /**      * 是否启动flag      */     private boolean started = false;     //日志文件后缀     private String suffix = ".log";      //是否有时间戳           private boolean timestamp = false;       private PrintWriter writer = null;     public void setDirectory(String directory) {         String oldDirectory = this.directory;         this.directory = directory; //如果目录文件有改变触发属性变更监听器         support.firePropertyChange("directory", oldDirectory, this.directory);     }     public void setPrefix(String prefix) {         String oldPrefix = this.prefix;         this.prefix = prefix;         support.firePropertyChange("prefix", oldPrefix, this.prefix);     }     public void setSuffix(String suffix) {         String oldSuffix = this.suffix;         this.suffix = suffix;         support.firePropertyChange("suffix", oldSuffix, this.suffix);     }     public boolean getTimestamp() {         return (timestamp);     }        public void setTimestamp(boolean timestamp) {         boolean oldTimestamp = this.timestamp;         this.timestamp = timestamp;         support.firePropertyChange("timestamp", new Boolean(oldTimestamp),                                    new Boolean(this.timestamp));     }     public void log(String msg) {         // 创建一个时间戳         Timestamp ts = new Timestamp(System.currentTimeMillis());         String tsString = ts.toString().substring(0, 19);         //截取日期信息         String tsDate = tsString.substring(0, 10);         // 如果日期和原信息不一致         if (!date.equals(tsDate)) { //线程安全的重新生成新的日志文件             synchronized (this) {                 if (!date.equals(tsDate)) {                     close();                     date = tsDate;                     open();                 }             }         }         // 想日志里面写信息         if (writer != null) { //如果设置了时间戳标识,则写时间戳信息+信息             if (timestamp) {                 writer.println(tsString + " " + msg);             } else { //如果没有设置时间戳,则直接写信息                 writer.println(msg);             }         }     }     private void close() { //将输出流的信息全部写入文件,并关闭输出流         if (writer == null)             return;         writer.flush();         writer.close();         writer = null;         date = "";     }     private void open() {         // 根据目录信息写文件         File dir = new File(directory); //如果dir不是绝对路径         if (!dir.isAbsolute()) //则获取容器安装目录,再通过directory定位文件绝对位置             dir = new File(System.getProperty("catalina.base"), directory); //创建目录         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;         }     } //增加监听信息     public void addLifecycleListener(LifecycleListener listener) {         lifecycle.addLifecycleListener(listener);     } //返回日志系统所有的监听器     public LifecycleListener[] findLifecycleListeners() {         return lifecycle.findLifecycleListeners();     } //删除某监听器     public void removeLifecycleListener(LifecycleListener listener) {         lifecycle.removeLifecycleListener(listener);     }  //启动日志系统     public void start() throws LifecycleException {         // Validate and update our current component state         if (started)             throw new LifecycleException                 (sm.getString("fileLogger.alreadyStarted"));         lifecycle.fireLifecycleEvent(START_EVENT, null);         started = true;     } //关闭日志系统     public void stop() throws LifecycleException {         // Validate and update our current component state         if (!started)             throw new LifecycleException                 (sm.getString("fileLogger.notStarted"));         lifecycle.fireLifecycleEvent(STOP_EVENT, null);         started = false;         close();     } }

2、将日志文件配置到容器中

复制代码
1
2
3
4
5
6
7
Context context = new SimpleContext(); FileLogger logger = new FileLogger(); logger.setPrefix("FileLog_"); logger.setSuffix(".txt"); logger.setTimestamp(true); logger.setDirectory("webroot"); context.setLogger(logger);

3、连接器获得容器的logger实例写信息

复制代码
1
2
3
4
5
6
7
8
9
10
private void log(String message) {     Logger logger = container.getLogger();     String localName = threadName;     if (localName == null)         localName = "HttpConnector";     if (logger != null)         logger.log(localName + " " + message);     else         System.out.println(localName + " " + message); }


4、HttpProcessor通过连接器获得容器的logger实例写信息

复制代码
1
2
3
4
5
private void log(String message) {     Logger logger = connector.getContainer().getLogger();     if (logger != null)         logger.log(threadName + " " + message); }


转载于:https://my.oschina.net/zjItLife/blog/613135

最后

以上就是可耐萝莉最近收集整理的关于servlet解析演进(5)-添加日志的全部内容,更多相关servlet解析演进(5)-添加日志内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部