目录
一、资料参考
二、数据库环境
1、创建表url_log
2、MBG创建通用代码
3、logService
三、拦截器
1、编写拦截器
2、配置拦截器
https://blog.csdn.net/shaohe18362202126/article/details/84310488
*如果不考虑日志存储在数据库中,可以略过此步骤。
DROP TABLE IF EXISTS `url_log`;
CREATE TABLE `url_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`creat_time` datetime DEFAULT NULL,
`op_name` varchar(255) DEFAULT NULL,
`op_id` int(11) DEFAULT NULL,
`request_url` varchar(255) DEFAULT NULL,
`request_method` varchar(255) DEFAULT NULL,
`request_params` varchar(255) DEFAULT NULL,
`response_status` varchar(255) DEFAULT NULL,
`controller_name` varchar(255) DEFAULT NULL,
`controller_method` varchar(255) DEFAULT NULL,
`cost_time` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
UrlLogMapper.java
UrlLog.java
UrlLogMapper.xml
/**
* @name: UrlLogService
* @description: log日志记录服务
* @author: StarFall
* @data: 2019年2月23日下午10:45:08
*/
@Service
public class UrlLogService {
@Autowired
private UrlLogMapper urlLogMapper;
/**
* 记录log
*
* @param log
*/
@Transactional
public void addLog(UrlLog log) {
urlLogMapper.insertSelectiveGetId(log);
}
/**
* 更新log
*
* @param log
*/
@Transactional
public void updateLog(UrlLog log) {
urlLogMapper.updateByPrimaryKeySelective(log);
}
}
在进行插入log的时候需要获取自增的主键,参考:https://blog.csdn.net/shaohe18362202126/article/details/84979873
/**
* @name: LoggerInterceptor
* @description: 日志拦截器记录操作日志
* @author: StarFall
* @data: 2019年2月23日下午9:46:41
*/
public class LoggerInterceptor implements HandlerInterceptor {
@Autowired
private UrlLogService urlLogService;
// log4j
private Logger logger = Logger.getLogger(LoggerInterceptor.class);
// 本地线程存储消耗时间变量
private static final ThreadLocal costTimeThreadLocal = new NamedThreadLocal<>("costTimeThreadLocal");
// 本地线程存储log的id
private static final ThreadLocal logIdThreadLocal = new NamedThreadLocal<>("logIdThreadLocal");
/**
* 该方法在目标方法之前被调用.
* 若返回值为 true, 则继续调用后续的拦截器和目标方法.
* 若返回值为 false, 则不会再调用后续的拦截器和目标方法.
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
long startTime = System.currentTimeMillis();
costTimeThreadLocal.set(startTime);
// logger日志记录
logger.debug("********************LoggerInterceptor.begin********************");
logger.debug(
"OpTime: " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS").format(new Date(startTime)));
logger.debug("RequestURL: " + request.getRequestURL());
logger.debug("RequestMethod: " + request.getMethod());
logger.debug("RequestParams: " + getParamString(request.getParameterMap()));
// 初始化UrlLog对象
UrlLog log = new UrlLog();
log.setCreatTime(new Date(startTime));
log.setRequestUrl(request.getRequestURL().toString());
log.setRequestMethod(request.getMethod());
if (handler instanceof HandlerMethod) {
HandlerMethod h = (HandlerMethod) handler;
logger.debug("ControllerName: " + h.getBean().getClass().getName());
logger.debug("ControllerMethod: " + h.getMethod().getName());
log.setControllerName(h.getBean().getClass().getName());
log.setControllerMethod(h.getMethod().getName());
}
log.setRequestParams(getParamString(request.getParameterMap()));
urlLogService.addLog(log);
// 获取自动生成的主键
Integer logId = log.getId();
logIdThreadLocal.set(logId);
return true;
}
/**
* 调用目标方法之后, 但在DispatcherServlet渲染视图之前被调用.
* 可以处理对应的ModelAndView
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.debug("响应状态: " + response.getStatus());
logger.debug("最大内存: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "m");
logger.debug("已分配内存: " + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "m");
logger.debug("已分配内存中的剩余空间: " + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "m");
logger.debug("最大可用内存: " + (Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory()
+ Runtime.getRuntime().freeMemory()) / 1024 / 1024 + "m");
long endTime = System.currentTimeMillis();
long startTime = costTimeThreadLocal.get();
logger.debug("耗时: " + (endTime - startTime) + "ms");
// 更新log对象
Integer logId = logIdThreadLocal.get();
UrlLog log = new UrlLog();
log.setId(logId);
log.setResponseStatus(String.valueOf(response.getStatus()));
log.setCostTime(String.valueOf((endTime - startTime) + "ms"));
urlLogService.updateLog(log);
logger.debug("********************LoggerInterceptor.end********************");
// 清除本地线程
logIdThreadLocal.remove();
costTimeThreadLocal.remove();
}
/**
* 在DispatcherServlet渲染视图之后被调用. 主要作用是释放资源
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
/**
* 从Map参数获取参数字符串
*
* @param map
* 参数map
* @return
*/
private String getParamString(Map map) {
StringBuilder sb = new StringBuilder();
for (Entry e : map.entrySet()) {
sb.append(e.getKey()).append("=");
String[] value = e.getValue();
if (value != null && value.length == 1) {
sb.append(value[0]).append("&");
} else {
sb.append(Arrays.toString(value)).append("&");
}
}
if (sb.length() >= 1) {
if (sb.substring(sb.length() - 1, sb.length()).equals("&")) {
sb.deleteCharAt(sb.length() - 1);
}
}
return sb.toString();
}
}
在applicationContext-servlet.xml中配置拦截器
参考文章:https://blog.csdn.net/u011781521/article/details/78624276