Tomcat中日誌組件
阿新 • • 發佈:2019-01-11
rri .com date 新的 form ret syn exceptio lse
Tomcat日誌組件
AccessLog接口
public interface AccessLog {
public void log(Request request, Response response, long time);
}
AccessLogAdapter
public class AccessLogAdapter implements AccessLog { private AccessLog[] logs; // 構造函數 public AccessLogAdapter(AccessLog log) { Objects.requireNonNull(log); logs = new AccessLog[] { log }; } // 添加新的 訪問日誌 AccessLog public void add(AccessLog log) { Objects.requireNonNull(log); AccessLog newArray[] = Arrays.copyOf(logs, logs.length + 1); newArray[newArray.length - 1] = log; logs = newArray; } // AccessLog 接口中的 log 方法,循環操作 @Override public void log(Request request, Response response, long time) { for (AccessLog log: logs) { log.log(request, response, time); } } }
Tomcat中日誌
? 默認在 server.xml 中配置了 AccessLogValve 。
<!-- server.xml Host 節點 --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" suffix=".txt" prefix="localhost_access_log" pattern="%h %l %u %t "%r" %s %b" /> <!-- className=org.apache.catalina.valves.AccessLogValve directory=logs 存儲位置 prefix 文件前綴 suffix 文件後綴 pattern 輸出格式 -->
@Override public void log(CharArrayWriter message) { System.out.println("log"); rotate(); /* In case something external rotated the file instead */ if (checkExists) { synchronized (this) { if (currentLogFile != null && !currentLogFile.exists()) { try { close(false); } catch (Throwable e) { ExceptionUtils.handleThrowable(e); log.info(sm.getString("accessLogValve.closeFail"), e); } /* Make sure date is correct */ dateStamp = fileDateFormatter.format( new Date(System.currentTimeMillis())); open(); } } } // Log this message try { synchronized(this) { if (writer != null) { message.writeTo(writer); writer.println(""); if (!buffered) { writer.flush(); } } } } catch (IOException ioe) { log.warn(sm.getString( "accessLogValve.writeFail", message.toString()), ioe); } }
調用過程
// ContainerBase
@Override
public void logAccess(Request request, Response response, long time,
boolean useDefault) {
boolean logged = false;
// 獲取 註冊的 日誌組件
AccessLog accessLog = getAccessLog();
if (accessLog != null) {
// 調用 適配器 log 方法
accessLog.log(request, response, time);
logged = true;
}
if (getParent() != null) {
getParent().logAccess(request, response, time,
(useDefault && !logged));
}
}
@Override
public AccessLog getAccessLog() {
// 默認 false
if (accessLogScanComplete) {
return accessLog;
}
// AccessLog 適配器
AccessLogAdapter adapter = null;
// 獲取所有註冊的 閥門 Valve
Valve valves[] = getPipeline().getValves();
for (Valve valve : valves) {
// 判斷 Valve 的類型
if (valve instanceof AccessLog) {
if (adapter == null) {
adapter = new AccessLogAdapter((AccessLog) valve);
} else {
adapter.add((AccessLog) valve);
}
}
}
if (adapter != null) {
accessLog = adapter;
}
accessLogScanComplete = true;
return accessLog;
}
自定義 AccessLog
在 server.xml 中 ,配置 Valve ,在解析 server.xml 會自動註冊。
public class WswAccessLogValve extends AbstractAccessLogValve {
@Override
protected void log(CharArrayWriter message) {
System.out.println("access log");
}
}
// message
// ||
// VV
// 0:0:0:0:0:0:0:1 - - [08/Dec/2018:23:47:07 +0800] "GET /tomcat/ HTTP/1.1" 200 139
<!-- server.xml Host 節點 -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" suffix=".txt"
prefix="localhost_access_log"
pattern="%h %l %u %t "%r" %s %b" />
<Valve className="org.apache.catalina.valves.WswAccessLogValve"/>
log // AccessLogValve 中輸出
access log // WswAccessLogValve 中輸出
Tomcat中日誌組件