Phân tích các yêu cầu HTTP bằng bộ lọc nhật ký Java
javax.servlet.FilterMột cách thuận tiện để triển khai và phân tích nội dung của các yêu cầu HTTP và nhật ký đầu ra.LọcGiới thiệu lớp học.
Bộ lọc nhật ký này sử dụng "java.util.logging.Logger" cho đầu ra nhật ký và bạn có thể thay đổi đầu ra thông tin bằng cách thay đổi cấp độ nhật ký.
javax.servlet.Filter là gì?
Khi xây dựng một ứng dụng web, ngoài xử lý nghiệp vụ chính, cần thực hiện xử lý phụ thông thường trước và sau xử lý nghiệp vụ chính.
Ví dụ: xác thực ứng dụng khách, kiểm tra quyền hạn, ghi nhật ký, v.v.
Việc mã hóa quá trình xử lý bên như vậy trong mỗi tài nguyên trở thành nguyên nhân chính cản trở khả năng bảo trì phần mềm, dẫn đến ứng dụng khó bảo trì.
Bằng cách triển khai javax.servlet.Filter, bạn thường có thể thực hiện quá trình xử lý bên này trước khi yêu cầu được chuyển đến lớp servlet.
Ngoài ra, vì cài đặt bộ lọc có thể được thực hiện trong web.xml nên bạn có thể thêm hoặc xóa bộ lọc một cách linh hoạt mà không cần thay đổi mã nguồn.
Hãy thử sử dụng bộ lọc nhật ký
Thực tế chúng ta hãy sử dụng bộ lọc nhật ký để lọc các yêu cầu HTTP và phân tích chúng.
Thời gian nàytomcatChúng tôi sẽ sử dụng ứng dụng ví dụ có sẵn ngay từ đầu.
Bạn có thể chạy bộ lọc này ngay lập tức bằng cách thực hiện các cài đặt sau.
2. Đặt tệp lớp đã biên dịch trong "/examples/WEB-INF/classes".
3.Đặt định nghĩa sau trong web.xml.
Bộ lọc nhật ký Bộ lọc nhật ký ghi nhật ký.Level KHỎE Bộ lọc nhật ký /*
*Mẫu url khi sử dụng khung Struts như sau.
*.LÀM
Vui lòng kiểm tra kết quả đầu ra của nhật ký khi thực hiện màn hình Ví dụ về phiên.
Thông tin nhật ký đầu ra và cấp độ nhật ký
●Ghi nội dung đầu ra
Thông tin nhật ký | mức đăng nhập |
---|---|
Thông tin cookie | KHỎE |
Thông tin tiêu đề HTTP | KHỎE |
HTTPThông tin khác | KHỎE |
Tham số yêu cầu HTTP | CẤU HÌNH |
đối tượng phạm vi yêu cầu | CẤU HÌNH |
đối tượng trong phạm vi phiên | CẤU HÌNH |
Mức sử dụng bộ nhớ trước và sau khi yêu cầu | CẤU HÌNH |
Thông tin chuyển đổi màn hình | THÔNG TIN |
Tốt nhất nên sử dụng các cấp độ nhật ký như sau.
- FINE: Xuất ra nhật ký chi tiết nhất. Đặt cài đặt này nếu bạn muốn phân tích chi tiết yêu cầu HTTP.
- CONFIG... Xuất ra nhật ký khá chi tiết. Đó là một ý tưởng tốt để giữ nó ở mức này trong giai đoạn phát triển.
- THÔNG TIN: Chỉ xuất ra thông tin chuyển tiếp màn hình.
●Cách thay đổi cấp độ nhật ký
Bạn có thể thay đổi mức đầu ra của nhật ký bằng cách đặt tham số khởi tạo log.Level.
ví dụ:
ghi nhật ký.Level THÔNG TIN
Mã nguồn
nhập javax.servlet.Filter;
nhập javax.servlet.FilterChain;
nhập javax.servlet.FilterConfig;
nhập javax.servlet.ServletException;
nhập javax.servlet.ServletRequest;
nhập javax.servlet.ServletResponse;
nhập javax.servlet.http.Cookie;
nhập javax.servlet.http.HttpServletRequest;
nhập javax.servlet.http.HttpServletResponse;
nhập javax.servlet.http.HttpSession;
/**
* Triển khai javax.servlet.Filter để phân tích nội dung của các yêu cầu HTTP và nhật ký đầu ra
* Lớp lọc.
*/
lớp công khai LogFilter triển khai Bộ lọc {
Trình ghi nhật ký tĩnh riêng tư logger =
Logger.getLogger(LogFilter.class.getName());
Chuỗi cuối cùng tĩnh riêng tư LINE_SEPA =
System.getProperty(“line.separator”);
Chuỗi cuối cùng tĩnh riêng tư NEXT_PAGE = “LogFilter.NEXT_PAGE”;
/**
* Khởi tạo bộ lọc nhật ký này.
* Ánh xạ @param
*/
public void init(ánh xạ FilterConfig) {
Chuỗi str = maps.getInitParameter(“logging.Level”);
System.out.println(“Đặt cấp độ nhật ký thành “+str+”.”);
Cấp độ = null;
thử {
cấp độ = Level.parse(str);
} bắt (Ngoại lệ e) {
e.printStackTrace();
cấp độ = Cấp độ.INFO;
}
LogManager.getLogManager().reset();
Trình xử lý trình xử lý = CustomConsoleHandler mới();
handler.setFormatter(new CustomFormatter());
handler.setLevel(level);
logger.setLevel(level);
logger.getParent().addHandler(handler);
}
/**
* Đây là bộ lọc xuất nhật ký.
* @param yêu cầu Yêu cầu HTTP đang được xử lý
* Phản hồi @param Phản hồi HTTP đang được tạo
* chuỗi @param
*/
public void doFilter(ServletRequest _request, ServletResponse _response,
chuỗi FilterChain) ném IOException, ServletException {
// --------------------" Sơ chế "
Yêu cầu HttpServletRequest = (HttpServletRequest) _request;
Phản hồi HttpServletResponse = (HttpServletResponse) _response;
if (logger.isLoggable(Level.CONFIG)) {
logger.config(
“============= Yêu cầu bắt đầu!!”
+”ID chủ đề:”
+ Thread.currentThread().hashCode()
+ ” ========================================================”);
}
// sử dụng bộ nhớ
Chuỗi hành độngMemory = null;
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = getMemoryInfo(” ”
+ Thời gian mới(System.currentTimeMillis()) + ”Yêu cầu[trước]”);
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(“Thông tin cookie” + getCookieInfo(request));
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(“Thông tin tiêu đề HTTP” + getHeadersInfo(request));
}
if (logger.isLoggable(Level.FINE)) {
tiều phu
.fine(“Thông tin khác về HTTP” + getRequestOtherInfo(request));
}
if (logger.isLoggable(Level.CONFIG)) {
Chuỗi reqlog = getRequestParametersInfo(request);
logger.config(“Tham số yêu cầu HTTP” + reqlog);
}
if (logger.isLoggable(Level.CONFIG)) {
logger.config(“đối tượng phạm vi yêu cầu”
+ getRequestAttributionInfo(request));
}
if (logger.isLoggable(Level.CONFIG)) {
Chuỗi sessionlog = getSessionInfo(request,true);
logger.config(“đối tượng phạm vi phiên (trước khi xử lý yêu cầu)”
+ nhật ký phiên);
}
// gọi bộ lọc tiếp theo
chain.doFilter(yêu cầu, phản hồi);
// ————————————————————- “Xử lý hậu kỳ”
if (logger.isLoggable(Level.CONFIG)) {
Chuỗi sessionlog = getSessionInfo(request,false);
logger.config(“đối tượng phạm vi phiên (sau khi xử lý yêu cầu)”
+ nhật ký phiên);
}
// sử dụng bộ nhớ
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = ”Mức sử dụng bộ nhớ trước và sau khi yêu cầu”+LINE_SEPA
+ Bộ nhớ hành động + LINE_SEPA
+ getMemoryInfo(” ” + Thời gian mới(System.currentTimeMillis())
+ ”yêu cầu[sau]”);
logger.config(actionMemory+LINE_SEPA);
}
// Thông tin chuyển màn hình
if (logger.isLoggable(Level.INFO)) {
Chuỗi nextPage = (Chuỗi) request.getAttribution(NEXT_PAGE);
if (nextPage == null || nextPage.length() == 0) {
nextPage = request.getRequestURI();
}
logger.info(“NEXT_PAGE=[” + nextPage + “], ”
+ “IP_ADDRESS=[” + request.getRemoteAddr() + “], ”
+ “SESSION_ID=[” + request.getSession().getId() + “], ”
+ “USER-AGENT=[” + request.getHeader(“user-agent”) + “]”);
}
if (logger.isLoggable(Level.CONFIG)) {
logger.config(
“============= Yêu cầu kết thúc!!”
+”ID chủ đề:”+ Thread.currentThread().hashCode()
+ ” =========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
hủy bỏ khoảng trống công khai () {
}
// ---------- Phương pháp riêng bên dưới -----------
Chuỗi tĩnh riêng tư getMemoryInfo(String tin nhắn) {
DecimalFormat dFromat = new DecimalFormat(“#,###KB”);
miễn phí dài = Runtime.getRuntime().freeMemory() / 1024;
tổng dài = Runtime.getRuntime().totalMemory() / 1024;
dài max = Runtime.getRuntime().maxMemory() / 1024;
sử dụng lâu dài = tổng cộng – miễn phí;
Tin nhắn chuỗi = tin nhắn + ” : ” + “total=” + dFromat.format(total) + “, ”
+ “Số tiền đã sử dụng=” + dFromat.format(used) + ” (” + (đã sử dụng * 100 / tổng cộng)
+ “%), khả dụng tối đa=” + dFromat.format(max);
tin nhắn trả lại;
}
/**
* Xuất tất cả các tiêu đề yêu cầu vào nhật ký.
*/
Chuỗi tĩnh riêng tư getHeadersInfo(HttpServletRequest request) {
Hỗ trợ StringBuffer = StringBuffer mới(LINE_SEPA);
Tiêu đề liệt kêNames = request.getHeaderNames();
trong khi (headerNames.hasMoreElements()) {
Chuỗi headerName = (Chuỗi) headerNames.nextElement();
buff.append(” “);
buff.append(headerName);
buff.append(“=”);
buff.append(request.getHeader(headerName));
buff.append(LINE_SEPA);
}
trả về buff.toString();
}
Chuỗi tĩnh riêng tư getCookieInfo(HttpServletRequest request) {
Hỗ trợ StringBuffer = StringBuffer mới();
Cookie[] cookies = request.getCookies();
if (cookie == null) {
trở lại "";
}
for (int i = 0; i < cookies.length; i++) {
buff.append(“\n — Cookie[” + i + “] —\n”);
buff.append(” “);
buff.append(cookie[i].getName());
buff.append(“=”);
buff.append(cookie[i].getValue());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getVersion()”);
buff.append(“=”);
buff.append(cookie[i].getVersion());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getComment()”);
buff.append(“=”);
buff.append(cookie[i].getComment());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getDomain()”);
buff.append(“=”);
buff.append(cookie[i].getDomain());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getMaxAge()”);
buff.append(“=”);
buff.append(cookie[i].getMaxAge());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getPath()”);
buff.append(“=”);
buff.append(cookie[i].getPath());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getSecure()”);
buff.append(“=”);
buff.append(cookie[i].getSecure());
buff.append(LINE_SEPA);
}
trả về buff.toString();
}
Chuỗi tĩnh riêng tư getRequestParametersInfo(HttpServletRequest request) {
Hỗ trợ StringBuffer = StringBuffer mới(LINE_SEPA);
Bản đồ bản đồ = ConvertRequest(request);
TreeMap trr = new TreeMap(map);
Iterator itr = trr.keySet().iterator();
trong khi (itr.hasNext()) {
Khóa chuỗi = (Chuỗi) itr.next();
buff.append(” “);
buff.append(key);
buff.append(“=”);
Giá trị đối tượng = map.get(key);
Giá trị chuỗi[] = giá trị (Chuỗi []);
if (value.length == 1) {
buff.append(values[0]);
} khác {
// Mảng chuỗi được chuyển đổi
Chuỗi strValue = tầng(giá trị);
buff.append(strValue);
}
buff.append(LINE_SEPA);
}
trả về buff.toString();
}
Chuỗi tĩnh riêng getRequestAttributionInfo(HttpServletRequest request) {
Hỗ trợ StringBuffer = StringBuffer mới(LINE_SEPA);
Bảng liệt kê e = request.getAttributionNames();
trong khi (e.hasMoreElements()) {
Tên chuỗi = (Chuỗi) e.nextElement();
buff.append(” name=” + name + “, attributeClass= ”
+ request.getAttribution(name).getClass().getName()
+ “, toString() = ” + request.getAttribution(name)
+ LINE_SEPA);
}
trả về buff.toString();
}
Chuỗi tĩnh riêng tư getRequestOtherInfo(HttpServletRequest request) {
Hỗ trợ StringBuffer = StringBuffer mới();
buff.append(LINE_SEPA);
buff.append(”getCharacterEncoding()=”);
buff.append(request.getCharacterEncoding());
buff.append(LINE_SEPA);
buff.append(”getContentLength()=”);
buff.append(request.getContentLength());
buff.append(LINE_SEPA);
buff.append(”getContentType()=”);
buff.append(request.getContentType());
buff.append(LINE_SEPA);
buff.append(”getLocale()=”);
buff.append(request.getLocale());
buff.append(LINE_SEPA);
buff.append(”getProtocol()=”);
buff.append(request.getProtocol());
buff.append(LINE_SEPA);
buff.append(”getRemoteAddr()=”);
buff.append(request.getRemoteAddr());
buff.append(LINE_SEPA);
buff.append(”getRemoteHost()=”);
buff.append(request.getRemoteHost());
buff.append(LINE_SEPA);
buff.append(”getScheme()=”);
buff.append(request.getScheme());
buff.append(LINE_SEPA);
buff.append(”getServerName()=”);
buff.append(request.getServerName());
buff.append(LINE_SEPA);
buff.append(”getServerPort()=”);
buff.append(request.getServerPort());
buff.append(LINE_SEPA);
buff.append(”isSecure()=”);
buff.append(request.isSecure());
buff.append(LINE_SEPA);
buff.append(”getAuthType()=”);
buff.append(request.getAuthType());
buff.append(LINE_SEPA);
buff.append(”getContextPath()=”);
buff.append(request.getContextPath());
buff.append(LINE_SEPA);
buff.append(”getMethod()=”);
buff.append(request.getMethod());
buff.append(LINE_SEPA);
buff.append(”getPathInfo()=”);
buff.append(request.getPathInfo());
buff.append(LINE_SEPA);
buff.append(”getPathTranslation()=”);
buff.append(request.getPathTranslation());
buff.append(LINE_SEPA);
buff.append(”getQueryString()=”);
buff.append(request.getQueryString());
buff.append(LINE_SEPA);
buff.append(”getRemoteUser()=”);
buff.append(request.getRemoteUser());
buff.append(LINE_SEPA);
buff.append(”getRequestedSessionId()=”);
buff.append(request.getRequestedSessionId());
buff.append(LINE_SEPA);
buff.append(”getRequestURI()=”);
buff.append(request.getRequestURI());
buff.append(LINE_SEPA);
buff.append(”getServletPath()=”);
buff.append(request.getServletPath());
buff.append(LINE_SEPA);
buff.append(”getUserPrincipal()=”);
buff.append(request.getUserPrincipal());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdFromCookie()=”);
buff.append(request.isRequestedSessionIdFromCookie());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdFromURL()=”);
buff.append(request.isRequestedSessionIdFromURL());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdValid()=”);
buff.append(request.isRequestedSessionIdValid());
buff.append(LINE_SEPA);
trả về buff.toString();
}
Chuỗi tĩnh riêng getSessionInfo(HttpServletRequest request,boolean before) {
Phiên HttpSession = request.getSession();
Hỗ trợ StringBuffer = StringBuffer mới();
buff.append(LINE_SEPA);
nếu (trước) {
buff.append(” session.isNew() = ” + session.isNew());
buff.append(LINE_SEPA);
buff.append(” session.getId() = ” + session.getId());
buff.append(LINE_SEPA);
}
Bảng liệt kê e = session.getAttributionNames();
trong khi (e.hasMoreElements()) {
Chuỗi sessionName = (Chuỗi) e.nextElement();
Chuỗi sessionClassName = session.getAttribution(sessionName)
.getClass().getName();
buff.append(” name =" + sessionName + ", value ="
+ session.getAttribution(sessionName) + “, attributeClass = ”
+ sessionClassName+LINE_SEPA);
}
trả về buff.toString();
}
chuyển đổi Hashtable tĩnh riêng tư (yêu cầu httpServletRequest) {
Hashtable tempHash = new Hashtable();
Bảng liệt kê e = request.getParameterNames();
trong khi (e.hasMoreElements()) {
Khóa chuỗi = (Chuỗi) e.nextElement();
Chuỗi [] giá trị = request.getParameterValues(key);
Chuỗi[] tham sốValues = Chuỗi mới[values.length];
for (int i = 0; i < value.length; i++) {
tham sốValues[i] = convUnicode(values[i]);
}
tempHash.put(key, tham sốValues);
}
trả về tempHash;
}
Tầng chuỗi tĩnh riêng tư (Giá trị đối tượng) {
nếu (giá trị == null) {
trả về “null”;
} else if (giá trị instanceof String[]) {
trả về giá trị convString((String[]));
} khác {
giá trị trả về.toString();
}
}
/**
* Trả về nội dung của mảng chuỗi [strArray] dưới dạng Chuỗi như bên dưới.
* “[temp1,temp2,temp3]”
* @param strArray Mảng chuỗi cần đánh giá
* @return String sau khi chuyển đổi
*/
Chuỗi tĩnh riêng tư convString(String[] strArray) {
nếu (strArray == null)
trả về giá trị rỗng;
Hỗ trợ StringBuffer = StringBuffer mới(“[“);
for (int i = 0; i < strArray.length; i++) {
buff.append(strArray[i] + “, “);
}
buff.delete(buff.length() – 2, buff.length());
buff.append(“]”);
trả về buff.toString();
}
/**
* Chuyển đổi [str] sang Unicode.
* @param str
* @trở lại
*/
Chuỗi tĩnh riêng tư convUnicode(String str) {
nếu (str == null)
trả về giá trị rỗng;
thử {
trả về Chuỗi mới(str.getBytes(“8859_1”), “JISAutoDetect”);
} bắt (UnsupportedEncodingException e) {
ném RuntimeException mới (e);
}
}
// ———————————————————————–
lớp tĩnh CustomFormatter mở rộng Formatter {
Mẫu chuỗi cuối cùng tĩnh = “yyyy/MM/dd HH:mm:ss”;
Định dạng chuỗi được đồng bộ hóa công khai (Bản ghi LogRecord) {
StringBuffer buf = new StringBuffer();
// đặt ngày và giờ
Ngày ngày = Ngày mới();
date.setTime(record.getMillis());
Trình định dạng SimpleDateFormat = new SimpleDateFormat(pattern);
buf.append(formatter.format(date));
buf.append(“:”);
// đặt mức
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(“:”);
buf.append(record.getMessage());
buf.append(LINE_SEPA);
return buf.toString();
}
}
lớp tĩnh CustomConsoleHandler mở rộng StreamHandler {
công khai CustomConsoleHandler() {
siêu();
setOutputStream(System.out);
}
/**
* Phát hành một LogRecord.
* Ban đầu, các yêu cầu ghi nhật ký được gửi đến đối tượng Logger.
* và đối tượng này khởi tạo LogRecord và
*Chuyển hướng tới đây.
*
* Bản ghi @param Mô tả sự kiện nhật ký. hồ sơ null chỉ đơn giản là bị bỏ qua
* và sẽ không có thông báo nào được gửi.
*/
xuất bản void công khai (Bản ghi LogRecord) {
super.publish(record);
tuôn ra();
}
/**
* Ghi đè StreamHandler.close để xóa, nhưng
* Luồng đầu ra không bị đóng. Nói cách khác, System.err không bị đóng.
*/
khoảng trống công khai đóng() {
tuôn ra();
}
}
}