所以我們只需要:
- 還援引
log(...)
前getNext().invoke(request,response)
- 修改
log(...)
區分 「之前」 和調用
最簡單的方式會一直 「之後」:
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
log(request, response, -1); // negative time indicates "before"
super.invoke(request, response);
}
但tomcat_6.0.16代碼不能很好地擴展,所以我以Thread.getName()
和「之前」/「之後」指示符作爲前綴日誌消息(以硬編碼的方式)。此外,我優選使用反射來訪問private AccessLogValve.getDate()
:
package org.apache.catalina.valves;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.ServletException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
public class PreAccessLogValve extends AccessLogValve {
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
long timeStart = System.currentTimeMillis();
log(request, response, -timeStart); // negative time indicates "before" request
getNext().invoke(request, response);
log(request, response, System.currentTimeMillis() - timeStart); // actual (positive) - "after"
}
public void log(Request request, Response response, long time) {
if (started && getEnabled() && null != logElements && (null == condition || null == request.getRequest().getAttribute(condition))) {
StringBuffer result = new StringBuffer();
try {
Date date = (Date) methodGetDate.invoke(this);
for (int i = 0; i < logElements.length; i++) {
logElements[i].addElement(result, date, request, response, time);
}
} catch (Throwable t) { t.printStackTrace(); }
log(Thread.currentThread().getName() + (time<0?" > ":" < ") + result.toString());
}
}
private static final Method methodGetDate;
static {
Method m = null;
try {
m = AccessLogValve.class.getDeclaredMethod("getDate");
m.setAccessible(true);
} catch (Throwable t) { t.printStackTrace(); }
methodGetDate = m;
}
}
編譯上述代碼與catalina.jar + servlet的api.jar文件和產生新卡塔利娜-my.jar,其被放置到Tomcat/lib文件夾。在此之後 - 我修改server.xml中有:
<Valve className="org.apache.catalina.valves.PreAccessLogValve"
directory="/tmp" prefix="test." suffix=".txt"
pattern="%a %t %m %U %s %b %D" resolveHosts="false" buffered="false"/>
這裏的示例輸出:
http-8007-exec-1 > 10.61.105.105 [18/Jan/2014:05:54:14 +0000] POST /admin/0$en_US/secure/enduser/search.do 200 - -1390024454470
http-8007-exec-5 > 10.61.105.105 [18/Jan/2014:05:54:17 +0000] GET /admin/0$en_US/secure/enduser/search.do 200 - -1390024457300
http-8007-exec-5 < 10.61.105.105 [18/Jan/2014:05:54:17 +0000] GET /admin/0$en_US/secure/enduser/search.do 200 13933 44
http-8007-exec-3 > 10.61.105.105 [18/Jan/2014:05:54:17 +0000] GET /admin/html/main.js 200 - -1390024457490
http-8007-exec-3 < 10.61.105.105 [18/Jan/2014:05:54:17 +0000] GET /admin/html/main.js 200 3750 0
http-8007-exec-5 > 10.61.105.105 [18/Jan/2014:05:54:17 +0000] GET /admin/images/layout/logo.gif 200 - -1390024457497
http-8007-exec-5 < 10.61.105.105 [18/Jan/2014:05:54:17 +0000] GET /admin/images/layout/logo.gif 200 1996 0
http-8007-exec-1 < 10.61.105.105 [18/Jan/2014:05:54:24 +0000] POST /admin/0$en_US/secure/enduser/search.do 200 13308 10209
這樣,所有「正在進行」的URI可以方便地隨時檢索:
[[email protected] tomcat]# awk '{if(">"==$2){if($1 in S)print S[$1];S[$1]=$0}else delete S[$1]}END{for(i in S)print S[i]}' test
http-8007-exec-4 > 10.61.105.105 [18/Jan/2014:06:13:20 +0000] GET /admin/images/1x1blank.gif 200 - -13
http-8007-exec-2 > 10.61.105.105 [18/Jan/2014:06:13:16 +0000] POST /admin/servlet/handlersvr 200 - -13
對於我遇到這個問題的一些報告,我讓他們在開始之前向表中插入一條記錄,並在完成時更新它,以跟蹤它運行的時間以及它被卡住的頻率。但是我提前知道哪些是servlet問題。 – developerwjk
@developerwjk - 是的,我正在尋找類似的東西,但在tomcat範圍內(或任何其他應用程序服務器)級別上,而不是在servlet級別上。 – Vlad