Menganalisis permintaan HTTP dengan filter log Java
javax.servlet.FilterIni mengimplementasikan alat praktis yang menganalisis isi permintaan HTTP dan menghasilkan log.MenyaringIzinkan saya memperkenalkan kelas ini.
Filter log ini menggunakan "java.util.logging.Logger" untuk output log, dan Anda dapat mengubah informasi output dengan mengubah level log.
Apa itu javax.servlet.Filter?
Saat membangun aplikasi web, selain proses bisnis utama, perlu dilakukan proses sekunder yang umum dilakukan sebelum dan sesudah proses tersebut.
Sebagai contoh, otentikasi klien, pemeriksaan izin, pencatatan log, dll.
Mengkodekan proses sekunder semacam itu di setiap sumber daya merupakan hambatan utama bagi pemeliharaan perangkat lunak dan menghasilkan aplikasi yang sulit dipelihara.
Dengan mengimplementasikan javax.servlet.Filter, Anda dapat melakukan pemrosesan sekunder ini secara bersamaan sebelum permintaan diteruskan ke kelas servlet.
Selain itu, karena pengaturan filter dapat dikonfigurasi di web.xml, Anda dapat secara fleksibel menambahkan atau menghapus filter tanpa mengubah kode sumber.
Mari kita coba menggunakan filter log.
Mari kita gunakan filter log untuk menganalisis permintaan HTTP dengan cara memfilternya.
Kali iniKucing jantanKita akan menggunakan aplikasi contoh yang sudah disertakan secara default.
Filter ini dapat dijalankan segera setelah melakukan pengaturan berikut.
2. Letakkan file kelas yang telah dikompilasi di bawah "/examples/WEB-INF/classes".
3. Tetapkan definisi berikut di web.xml.
Filter Log Filter Log penebangan. Level BAGUS Filter Log /*
*Pola URL saat menggunakan framework Struts adalah sebagai berikut:
*.Mengerjakan
Silakan periksa hasil output log saat Anda menjalankan layar Contoh Sesi.

Informasi log untuk output dan level log.
●Isi keluaran log
| Informasi log | Tingkat log |
|---|---|
| Informasi Cookie | BAGUS |
| Informasi Header HTTP | BAGUS |
| HTTP dan informasi lainnya | BAGUS |
| Parameter Permintaan HTTP | KONFIGURASI |
| Objek yang cakupannya terbatas pada permintaan | KONFIGURASI |
| Objek yang cakupannya sesi | KONFIGURASI |
| Penggunaan memori sebelum dan sesudah permintaan | KONFIGURASI |
| Informasi transisi layar | INFO |
Anda harus menggunakan level log berikut untuk membedakan antara keduanya.
- BAIK... Menampilkan log paling detail. Atur ini jika Anda ingin menganalisis permintaan HTTP secara detail.
- CONFIG... menghasilkan log yang sedikit lebih detail. Sebaiknya tetap pada level ini selama pengembangan.
- INFO... Hanya menampilkan informasi transisi layar.
● Cara mengubah level log
Anda dapat mengubah level output log dengan mengatur parameter inisialisasi logging.Level.
contoh:
penebangan. Level INFO
Kode sumber
impor javax.servlet.Filter;
impor javax.servlet.FilterChain;
impor javax.servlet.FilterConfig;
impor javax.servlet.ServletException;
impor javax.servlet.ServletRequest;
impor javax.servlet.ServletResponse;
impor javax.servlet.http.Cookie;
impor javax.servlet.http.HttpServletRequest;
impor javax.servlet.http.HttpServletResponse;
impor javax.servlet.http.HttpSession;
/**
* Implementasikan javax.servlet.Filter untuk mengurai isi permintaan HTTP dan menghasilkan log output.
* Kelas filter.
*/
kelas publik LogFilter mengimplementasikan Filter {
private static Logger logger =
Logger.getLogger(LogFilter.class.getName());
privat statis final String LINE_SEPA =
System.getProperty(“pemisah garis”);
private static final String NEXT_PAGE = “LogFilter.NEXT_PAGE”;
/**
* Inisialisasi filter log ini.
* @param mapping
*/
publik void init(pemetaan FilterConfig) {
String str = mapping.getInitParameter(“logging.Level”);
System.out.println("Mengatur level log ke "+str+".");
Level level = null;
mencoba {
level = Level.parse(str);
} catch (Exception e) {
e.printStackTrace();
level = Level.INFO;
}
LogManager.getLogManager().reset();
Handler handler = new CustomConsoleHandler();
handler.setFormatter(new CustomFormatter());
handler.setLevel(level);
logger.setLevel(level);
logger.getParent().addHandler(penangan);
}
/**
* Ini adalah filter yang menghasilkan log.
* @param request Permintaan HTTP yang sedang diproses
* @param response Respons HTTP yang sedang dihasilkan
* @param chain
*/
public void doFilter(ServletRequest _request, ServletResponse _response,
FilterChain chain) throws IOException, ServletException {
// —————————————————————『Praproses』
HttpServletRequest request = (HttpServletRequest) _request;
HttpServletResponse response = (HttpServletResponse) _response;
jika (logger.isLoggable(Level.CONFIG)) {
logger.Config(
“============ Permintaan Dimulai!!”
+"ID Utas:"”
+ Thread.currentThread().hashCode()
+ ” =========================================================” Hak Cipta;
}
// Penggunaan memori
String actionMemory = null;
jika (logger.isLoggable(Level.CONFIG)) {
actionMemory = getMemoryInfo(" "”
+ new Time(System.currentTimeMillis()) + " Permintaan [Sebelumnya]");
}
jika (logger.isLoggable(Level.FINE)) {
logger.fine("Informasi cookie" + getCookieInfo(request));
}
jika (logger.isLoggable(Level.FINE)) {
logger.fine("Informasi Header HTTP" + getHeadersInfo(request));
}
jika (logger.isLoggable(Level.FINE)) {
pencatat
.fine("Informasi Lain HTTP" + getRequestOtherInfo(request));
}
jika (logger.isLoggable(Level.CONFIG)) {
String reqlog = getRequestParametersInfo(request);
logger.config("Parameter permintaan HTTP" + reqlog);
}
jika (logger.isLoggable(Level.CONFIG)) {
logger.config("objek lingkup permintaan")“
+ getRequestAttributeInfo(request));
}
jika (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request, true);
logger.config("objek lingkup sesi (sebelum pemrosesan permintaan)")“
+ log sesi);
}
// Panggil filter berikut
chain.doFilter(permintaan, respons);
// ———————————————————-『Pemrosesan Pasca-produksi』
jika (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(request, false);
logger.config("objek lingkup sesi (setelah pemrosesan permintaan)")“
+ log sesi);
}
// Penggunaan memori
jika (logger.isLoggable(Level.CONFIG)) {
actionMemory = "Penggunaan memori sebelum dan sesudah permintaan" + LINE_SEPA
+ actionMemory + LINE_SEPA
+ getMemoryInfo(" " + new Time(System.currentTimeMillis())
+ "Permintaan [setelah]");
logger.config(actionMemory+LINE_SEPA);
}
// Informasi transisi layar
jika (logger dapat mencatat Level.INFO)) {
String nextPage = (String) request.getAttribute(NEXT_PAGE);
if (nextPage == null || nextPage.length() == 0) {
Halaman berikutnya = permintaan.getRequestURI();
}
logger.info(“NEXT_PAGE=[” + nextPage + “], ”
+ “ALAMAT_IP=[” + request.getRemoteAddr() + “], ”
+ “SESSION_ID=[” + request.getSession().getId() + “], ”
+ “USER-AGENT=[” + request.getHeader(“user-agent”) + “]”);
}
jika (logger.isLoggable(Level.CONFIG)) {
logger.Config(
“============ Permintaan Berakhir!!”
+"ID Thread:"+ Thread.currentThread().hashCode()
+ ” =========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
publik void destroy() {
}
// ------- Metode privat di bawah ini -------
private static String getMemoryInfo(String message) {
DecimalFormat dFromat = new DecimalFormat(“#,###KB”);
long free = Runtime.getRuntime().freeMemory() / 1024;
total panjang = Runtime.getRuntime().totalMemory() / 1024;
long max = Runtime.getRuntime().maxMemory() / 1024;
Digunakan dalam waktu lama = total – gratis;
String msg = message + ": " + "Total=" + dFromat.format(total) + ", "”
+ “Penggunaan =" + dFromat.format(digunakan) + ” (” + (digunakan * 100 / total)
+ “%), maksimum yang tersedia=” + dFromat.format(max);
kembalikan pesan;
}
/**
* Catat semua header permintaan.
*/
private static String getHeadersInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Enumerasi headerNames = request.getHeaderNames();
selama (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
buff.append("");
buff.append(headerName);
buff.append("=");
buff.append(request.getHeader(headerName));
buff.append(LINE_SEPA);
}
return buff.toString();
}
private static String getCookieInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer();
Cookie[] cookies = request.getCookies();
jika (cookies == null) {
kembali "";
}
for (int i = 0; i < cookies.length; i++) {
buff.append(“\n — Cookie[” + i + “] —\n”);
buff.append("");
buff.append(cookies[i].getName());
buff.append("=");
buff.append(cookies[i].getValue());
buff.append(LINE_SEPA);
buff.append("");
buff.append(“getVersion()”);
buff.append("=");
buff.append(cookies[i].getVersion());
buff.append(LINE_SEPA);
buff.append("");
buff.append(“getComment()”);
buff.append("=");
buff.append(cookies[i].getComment());
buff.append(LINE_SEPA);
buff.append("");
buff.append(“getDomain()”);
buff.append("=");
buff.append(cookies[i].getDomain());
buff.append(LINE_SEPA);
buff.append("");
buff.append(“getMaxAge()”);
buff.append("=");
buff.append(cookies[i].getMaxAge());
buff.append(LINE_SEPA);
buff.append("");
buff.append("getPath()");
buff.append("=");
buff.append(cookies[i].getPath());
buff.append(LINE_SEPA);
buff.append("");
buff.append(“getSecure()”);
buff.append("=");
buff.append(cookies[i].getSecure());
buff.append(LINE_SEPA);
}
return buff.toString();
}
private static String getRequestParametersInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Map map = convertRequest(request);
TreeMap trr = new TreeMap(map);
Iterator itr = trr.keySet().iterator();
sementara (itr memiliki Next()) {
String key = (String) itr.next();
buff.append("");
buff.append(key);
buff.append("=");
Nilai objek = map.get(key);
String[] values = (String[]) value;
if (values.length == 1) {
buff.append(values[0]);
kalau tidak {
// Konversi array String.
String strValue = stratum(values);
buff.append(strValue);
}
buff.append(LINE_SEPA);
}
return buff.toString();
}
private static String getRequestAttributeInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer(LINE_SEPA);
Enumerasi e = request.getAttributeNames();
selama (e memiliki Lebih BanyakElemen()) {
String name = (String) e.nextElement();
buff.append(" name=" + name + ", attributeClass=")”
+ request.getAttribute(name).getClass().getName()
+ “, toString() = ” + request.getAttribute(name)
+ LINE_SEPA);
}
return buff.toString();
}
private static String getRequestOtherInfo(HttpServletRequest request) {
StringBuffer buff = new StringBuffer();
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("getPathTranslated()=");
buff.append(request.getPathTranslated());
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);
return buff.toString();
}
private static String getSessionInfo(HttpServletRequest request, boolean before) {
HttpSession session = request.getSession();
StringBuffer buff = new StringBuffer();
buff.append(LINE_SEPA);
jika (sebelumnya) {
buff.append(" session.isNew() = " + session.isNew());
buff.append(LINE_SEPA);
buff.append(" session.getId() = " + session.getId());
buff.append(LINE_SEPA);
}
Enumerasi e = sesi.getAttributeNames();
selama (e memiliki Lebih BanyakElemen()) {
String sessionName = (String) e.nextElement();
String sessionClassName = session.getAttribute(sessionName)
.getClass().getName();
buff.append(" nama =" + sessionName + ", nilai ="”
+ session.getAttribute(sessionName) + “, attributeClass = ”
+ sessionClassName+LINE_SEPA);
}
return buff.toString();
}
private static Hashtable convertRequest(HttpServletRequest request) {
Hashtable tempHash = new Hashtable();
Enumerasi e = request.getParameterNames();
selama (e memiliki Lebih BanyakElemen()) {
String key = (String) e.nextElement();
String[] values = request.getParameterValues(key);
String[] parameterValues = new String[values.length];
for (int i = 0; i < values.length; i++) {
parameterValues[i] = convUnicode(values[i]);
}
tempHash.put(key, parameterValues);
}
kembalikan tempHash;
}
privat statis String stratum(Objek nilai) {
jika (nilai == null) {
kembalikan "null";
} else if (value instanceof String[]) {
kembalikan convString((String[]) nilai);
kalau tidak {
return value.toString();
}
}
/**
* Mengembalikan isi dari array string [strArray] sebagai String, seperti yang ditunjukkan di bawah ini.
* “[temp1,temp2,temp3]”
* @param strArray Array String yang akan dievaluasi.
* @return string yang telah dikonversi
*/
private static String convString(String[] strArray) {
jika (strArray == null)
kembalikan null;
StringBuffer buff = new StringBuffer(“[“);
for (int i = 0; i < strArray.length; i++) {
buff.append(strArray[i] + “, “);
}
buff.delete(buff.length() – 2, buff.length());
buff.append("]");
return buff.toString();
}
/**
* Mengonversi [str] ke Unicode.
* @param str
* @kembali
*/
private static String convUnicode(String str) {
jika (str == null)
kembalikan null;
mencoba {
kembalikan String baru (str.getBytes(“8859_1”), “JISAutoDetect”);
} catch (UnsupportedEncodingException e) {
lempar RuntimeException baru(e);
}
}
// ———————————————————————–
kelas statis CustomFormatter extends Formatter {
static final String pattern = “yyyy/MM/dd HH:mm:ss”;
publik disinkronkan String format(LogRecord record) {
StringBuffer buf = new StringBuffer();
// Atur tanggal dan waktu
Date date = new Date();
tanggal.setTime(record.getMillis());
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
buf.append(formatter.format(date));
buf.append(":");
// Atur level
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(":");
buf.append(record.getMessage());
buf.append(LINE_SEPA);
return buf.toString();
}
}
kelas statis CustomConsoleHandler extends StreamHandler {
publik CustomConsoleHandler() {
super();
setOutputStream(System.out);
}
/**
* Sebuah LogRecord akan diterbitkan.
* Pada keadaan awal, permintaan pencatatan diarahkan ke objek Logger.
* Hal ini dilakukan sebagai respons, dan objek ini menginisialisasi LogRecord
* Ini telah diteruskan ke sini.
*
* @param record Deskripsi peristiwa log. Record null akan diabaikan begitu saja.
* Tidak ada pemberitahuan yang akan dikirim.
*/
public void publish(LogRecord record) {
super.publish(record);
menyiram();
}
/**
Meskipun Anda menimpa StreamHandler.close untuk melakukan flush,
* Aliran keluaran tidak akan ditutup. Dengan kata lain, System.err tidak akan ditutup.
*/
publik void tutup() {
menyiram();
}
}
}
