背景
对于很多后台管理系统来说,权限较多,对系统操作的人也会多。如此以来,对于一些操作的记录就非常有必要了,从而可以清楚的追踪对系统进行操作的人以及做了哪些操作,并且可以快速排查定位一些问题。下面简单说一下自己设计的思路。
整体思路
基于spring 拦截器和java的注解,并且通过多线程形式异步向数据库中插入操作日志来实现操作日志功能模块。
1.数据库设计
主日志mainlog表
记录主日志相关信息
子日志表childlog
记录子操作日志信息
2.java自定义注解
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MainAnnotation {
int maintype() default 0;
String type() default "0";
String tables() default "";
String desc() default "";
}
3.spring拦截器
public class MainInterceptor extends HandlerInterceptorAdapter{
private static final ThreadLocal<Long> mailogthreadLocal = new ThreadLocal<Long>();
//前置拦截
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return super.preHandle(request, response, handler);
}
mailogthreadLocal.set(System.currentTimeMillis());
return super.preHandle(request, response, handler);
}
//后置拦截
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (!(handler instanceof HandlerMethod)) {
super.preHandle(request, response, handler);
return;
}
HandlerMethod method = (HandlerMethod)handler;
MainAnnotation mainlog = method.getMethodAnnotation(MainAnnotation.class);
if(mainlog != null) {
String desc = mainlog.desc();
int maintype = mainlog.maintype();
String type = mainlog.type();
String tables = mainlog.tables();
String username = (String) request.getSession().getAttribute("username");
long costtime = (int) (System.currentTimeMillis()-get());
LogUtil.writeMainLog(new MainLogEntity(maintype, username, tables, desc, costtime),list);//异步插入数据库日志记录
}
}
4.异步插入数据库日志记录
public class LogUtil {
private final static Logger logger = LoggerFactory.getLogger(LogUtil.class);
private static ExecutorService executorService = Executors.newFixedThreadPool(2);
private static MainServiceImpl mainService = SpringContextHolder.getBean("mainServiceImpl");
public static void writeMainLog(MainEntity log, List<ChildEntity> list) {
executorService.execute(new Runnable() {
@Override
public void run() {
try {
if (mainService != null) {
logger.info("---插入日志start---");
int issuccess = mainService.insertlog(log);
int mainid = log.getId();
if (list != null && issuccess > 0 && mainid > 0) {
for (ChildLogEntity clog : list) {
clog.setMainlogid(mainid);
}
mainService.insertchildlog(list);
}
logger.info("---插入日志end---");
} else {
logger.error("spring init bean mainService fail,please check configs");
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}