之前说过了数据的采集是最重要的,现在就分三步来采集需要处理的日志数据。话不多说,直接上代码,不一定适合别人。
public class LogInterceptor implements HandlerInterceptor {
//日志对象
Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
//当前请求用户标识
private static final String LOGGER_SEND_USER = "_logger_send_user";
//请求开始时间标识
private static final String LOGGER_SEND_TIME = "_logger_send_time";
//请求日志实体标识
private static final String LOGGER_ENTITY = "_logger_entity";
//请求返回数据标识
public static final String LOGGER_RETURN = "_logger_return";
public static final ThreadLocal<Map<String,String>> threadLocal = new ThreadLocal<Map<String,String>>(){
@Override
protected Map<String,String> initialValue()
{
return null;
}
};
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
…… 逻辑代码
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
……
LogInfoDto logInfoDto = new LogInfoDto();
logInfoDto.setUrl(uri);
logInfoDto.setProject(LogClientConfig.getValue(LogCfgEnum.Project));
……
//这里调用进程内日志发送接口
LogSenderFactory.getLogSender().send(logInfoDto);
LogInterceptor.threadLocal.remove();
}
/**
* 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
*
* @param request
* @return
* @throws IOException
*/
public String getIpAddress(HttpServletRequest request) throws IOException {
// 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = (String) ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
}
}
可以看到实现方法就是实现HandlerInterceptor接口来拦截日志信息。
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;
void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
中间还用了线程变量threadLocal(老司机用的,不是很懂)。