package tsar.tomcat.status;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by peiliping on 16-7-25.
*/
public class TsarFilter implements Filter {
static AtomicLong IN = new AtomicLong(0);
static AtomicLong OUT = new AtomicLong(0);
static AtomicLong COST = new AtomicLong(0);
static AtomicLong[] HTTPCODES = new AtomicLong[5];
static AtomicBoolean HEALTH = new AtomicBoolean(true);
{
for (int i = 0; i < 5; i++)
HTTPCODES[i] = new AtomicLong(0);
}
String status_url = "/tomcat_status";
String health_url = "/health_status";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String tomcat_status_path = filterConfig.getInitParameter("status_url");
if (tomcat_status_path != null && tomcat_status_path.trim().length() > 0) {
this.status_url = tomcat_status_path.trim();
}
String health_status_path = filterConfig.getInitParameter("health_url");
if (health_status_path != null && health_status_path.trim().length() > 0) {
this.health_url = health_status_path.trim();
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
chain.doFilter(request, response);
}
TsarFilter.IN.incrementAndGet();
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
try {
if (status_url.equals(httpRequest.getRequestURI())) {
printStatusResult(httpResponse);
} else if (health_url.equals(httpRequest.getRequestURI())) {
if (httpRequest.getParameter("status") != null) {
HEALTH.set(Boolean.valueOf(httpRequest.getParameter("status")));
}
printHealthResult(httpResponse);
} else {
chain.doFilter(request, response);
}
} finally {
TsarFilter.OUT.incrementAndGet();
}
}
private void printHealthResult(HttpServletResponse response) throws IOException {
boolean health = HEALTH.get();
StringBuilder sb = new StringBuilder();
sb.append("health:").append(health).append("\n");
byte[] result = sb.toString().getBytes(Charset.forName("UTF-8"));
response.setHeader("Pragma", "no-cache");
response.addHeader("Cache-Control", "must-revalidate,no-cache,no-store");
response.setDateHeader("Expires", 0);
response.setContentType("text/html; charset=UTF-8");
response.setContentLength(result.length);
response.getOutputStream().write(result);
response.flushBuffer();
}
private void printStatusResult(HttpServletResponse response) throws IOException {
long out = OUT.get();
long in = IN.get();
long cost = COST.get();
StringBuilder sb = new StringBuilder();
sb.append("active:").append(in - out).append("\n");
sb.append("accepts:").append(in).append("\n");
sb.append("handled:").append(out).append("\n");
sb.append("1XX:").append(HTTPCODES[0].get()).append("\n");
sb.append("2XX:").append(HTTPCODES[1].get()).append("\n");
sb.append("3XX:").append(HTTPCODES[2].get()).append("\n");
sb.append("4XX:").append(HTTPCODES[3].get()).append("\n");
sb.append("5XX:").append(HTTPCODES[4].get()).append("\n");
sb.append("request_time:").append(cost).append("\n");
byte[] result = sb.toString().getBytes(Charset.forName("UTF-8"));
response.setHeader("Pragma", "no-cache");
response.addHeader("Cache-Control", "must-revalidate,no-cache,no-store");
response.setDateHeader("Expires", 0);
response.setContentType("text/html; charset=UTF-8");
response.setContentLength(result.length);
response.getOutputStream().write(result);
response.flushBuffer();
}
@Override
public void destroy() {}
}