用戶點擊了某個界面,請求了後臺某個接口。接口請求到後臺後,記錄請求的數據到數據庫中。html
一、自定義一個註解,被加註解的方法,請求的數據被保存下來 二、定義一個aop 去攔截被註解的方法 三、寫一個線程池、執行攔截後的邏輯。也就是保存到數據庫中java
查看到剛剛請求用戶列表界面的執行狀況git
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SLog { String value() default ""; }
@Aspect @Component public class SLogAspect { /** * 保存日誌到數據庫的線程池 */ ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("SLogAspect-Thread-%d").build(); ExecutorService executor = new ThreadPoolExecutor(5,200,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), threadFactory, new ThreadPoolExecutor.AbortPolicy()); @Pointcut("@annotation(com.slife.annotation.SLog)") public void logPointCut() { } @Around("logPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); // 執行方法 Object result = point.proceed(); // 執行時長(毫秒) long time = System.currentTimeMillis() - beginTime; // 獲取request HttpServletRequest request = ServletUtils.getHttpServletRequest(); //獲取請求的ip String ip = IPUtils.getIpAddr(request); SaveLogTask saveLogTask = new SaveLogTask(point, time, ip); //保存日誌到數據庫 executor.execute(saveLogTask); return result; } }
/** * * @author chen * @date 2017/9/19 * <p> * Email 122741482@qq.com * <p> * Describe: */ public class SaveLogTask implements Runnable { private SlifeLogDao slifeLogDao = ApplicationContextRegister.getBean(SlifeLogDao.class); private ProceedingJoinPoint joinPoint; private long time; private String ip; public SaveLogTask(ProceedingJoinPoint point, long time, String ip) { this.joinPoint = point; this.time = time; this.ip = ip; } @Override public void run() { saveLog(joinPoint, time, ip); } /** * 保存日誌 到數據庫 * * @param joinPoint * @param time */ private void saveLog(ProceedingJoinPoint joinPoint, long time, String ip) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SlifeLog slifeLog = new SlifeLog(); SLog sLog = method.getAnnotation(SLog.class); if (slifeLog != null) { // 註解上的描述 slifeLog.setMsg(sLog.value()); } // 請求的方法名 String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); slifeLog.setSrc(className + "." + methodName + "()"); // 請求的參數 Object[] args = joinPoint.getArgs(); try { String params = JSON.toJSONString(args[0]); slifeLog.setParams(params); } catch (Exception e) { } // 設置IP地址 slifeLog.setIp(ip); // 用戶名 ShiroUser currUser = SlifeSysUser.ShiroUser(); if (null == currUser) { if (null != slifeLog.getParams()) { slifeLog.setName(slifeLog.getParams()); slifeLog.setLoginName(slifeLog.getParams()); } else { slifeLog.setName("獲取用戶信息爲空"); slifeLog.setLoginName("獲取用戶信息爲空"); slifeLog.setCreateId(-1L); } } else { slifeLog.setName(currUser.getName()); slifeLog.setLoginName(currUser.getUsername()); } slifeLog.setUseTime(time); // 保存系統日誌 slifeLogDao.insert(slifeLog); } }
@SLog("獲取用戶列表數據") @ApiOperation(value = "獲取用戶列表數據", notes = "獲取用戶列表:使用約定的DataTable") @PostMapping(value = "/list") @ResponseBody public DataTable<SysUser> list(@RequestBody DataTable dt, ServletRequest request) { return sysUserService.pageSearch(dt); } @SLog("獲取用戶列表數據")
簡單的一個 記錄請求的日誌 實現。github
這裏把保存到數據庫的邏輯寫到了一個線程池中,主要是不但願記錄日誌的邏輯影響了用戶請求數據接口的邏輯,和性能。數據庫
個人官網 app
個人官網http://guan2ye.com 個人CSDN地址http://blog.csdn.net/chenjianandiyi 個人簡書地址http://www.jianshu.com/u/9b5d1921ce34 個人githubhttps://github.com/javanan 個人碼雲地址https://gitee.com/jamen/ 阿里雲優惠券https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=vf2b5zld&utm_source=vf2b5zldide