當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
slf4j注解log报错_SpringBoot自定义日志注解,用于数据库记录操作日志,你用过吗?...
生活随笔
收集整理的這篇文章主要介紹了
slf4j注解log报错_SpringBoot自定义日志注解,用于数据库记录操作日志,你用过吗?...
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
大家好,我是程序員7歌!
今天我將為大家講解如何通過自定義注解記錄接口訪問日志。一般的開發中,有兩種方式可以記錄日志信息,第一種:把接口日志信息保存到日志文件中,第二種:把接口操作日志保存到數據庫中,這里我將為大家講解第二種方式。
創建日志表
在數據庫新增日志記錄表,字段我們可以自定義,其中有幾個必要字段,如下:
- type:請求類型
- title:操作記錄(日志標題)
- remote_addr:操作IP地址
- username:操作人
- request_uri:接口地址
- http_method:接口類型
- class_method:請求的接口方法
- params:請求參數數據
- session_id:用戶session
以下就是數據庫表結構:
DROP TABLE IF EXISTS `sys_log`;CREATE TABLE `sys_log` ( `id` bigint(50) NOT NULL AUTO_INCREMENT COMMENT '編號', `type` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT '請求類型', `title` varchar(255) COLLATE utf8_bin DEFAULT '' COMMENT '日志標題', `remote_addr` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '操作IP地址', `username` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '操作用戶昵稱', `request_uri` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '請求URI', `http_method` varchar(10) COLLATE utf8_bin DEFAULT NULL COMMENT '操作方式', `class_method` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '請求類型.方法', `params` text COLLATE utf8_bin COMMENT '操作提交的數據', `session_id` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'sessionId', `response` longtext COLLATE utf8_bin COMMENT '返回內容', `use_time` bigint(11) DEFAULT NULL COMMENT '方法執行時間', `browser` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '瀏覽器信息', `area` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '地區', `province` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '省', `city` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '市', `isp` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '網絡服務提供商', `exception` text COLLATE utf8_bin COMMENT '異常信息', `create_by` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '創建者', `create_date` datetime DEFAULT NULL COMMENT '創建時間', `update_by` bigint(64) DEFAULT NULL, `update_date` datetime DEFAULT NULL, `remarks` varchar(255) COLLATE utf8_bin DEFAULT NULL, `del_flag` bit(1) DEFAULT NULL, PRIMARY KEY (`id`), KEY `sys_log_create_by` (`create_by`) USING BTREE, KEY `sys_log_request_uri` (`request_uri`) USING BTREE, KEY `sys_log_type` (`type`) USING BTREE, KEY `sys_log_create_date` (`create_date`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=150 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='系統日志';使用自動生成代碼工具生成SysLog類的信息:SysLog/SysLogController/SysLogService/SysLogServiceImpl/SysLogMapper/SysLogMapper.xml,結構如下圖:
自定義日志注解
在項目中新增自定義注解,用于注解哪些接口需要記錄操作日志,代碼如下:
package com.july.annotation;import java.lang.annotation.*;/** * 系統日志注解 * @author zqk * @since 2019/12/5 */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface SysLog { String value() default "";}在定義一個Aspect切面類,里面可以定義切入點和通知,核心代碼如下:
package com.july.aspect;import com.alibaba.fastjson.JSONObject;import com.july.entity.SysLog;import com.july.service.SysLogService;import com.july.util.ToolUtil;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;import org.springframework.util.StringUtils;import org.springframework.web.context.request.RequestAttributes;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import java.lang.reflect.Method;import java.util.Map;/** * 解析響應數據 * @author zqk * @since 2019/12/5 */@Aspect@Order(5)@Component@Slf4jpublic class WebLogAspect { @Resource private SysLogService sysLogService; private ThreadLocal startTime = new ThreadLocal<>(); private SysLog sysLog = null; @Pointcut("@annotation(com.july.annotation.SysLog)") public void webLog(){} @Before("webLog()") public void doBefore(JoinPoint joinPoint) { startTime.set(System.currentTimeMillis()); // 接收到請求,記錄請求內容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); HttpSession session = (HttpSession) attributes.resolveReference(RequestAttributes.REFERENCE_SESSION); sysLog = new SysLog(); sysLog.setClassMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); sysLog.setHttpMethod(request.getMethod()); //獲取傳入目標方法的參數 Object[] args = joinPoint.getArgs(); for (int i = 0; i < args.length; i++) { Object o = args[i]; if(o instanceof ServletRequest || (o instanceof ServletResponse) || o instanceof MultipartFile){ args[i] = o.toString(); } } String str = JSONObject.toJSONString(args); sysLog.setParams(str.length()>5000? JSONObject.toJSONString("請求參數數據過長不與顯示"):str); String ip = ToolUtil.getClientIp(request); if("0.0.0.0".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip) || "localhost".equals(ip) || "127.0.0.1".equals(ip)){ ip = "127.0.0.1"; } sysLog.setRemoteAddr(ip); sysLog.setRequestUri(request.getRequestURL().toString()); if(session != null){ sysLog.setSessionId(session.getId()); } MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); com.july.annotation.SysLog mylog = method.getAnnotation(com.july.annotation.SysLog.class); if(mylog != null){ //注解上的描述 log.info("注解信息 ===> " + mylog.value()); sysLog.setTitle(mylog.value()); } Map browserMap = ToolUtil.getOsAndBrowserInfo(request); sysLog.setBrowser(browserMap.get("os")+"-"+browserMap.get("browser")); if(!"127.0.0.1".equals(ip)){ Map map = ToolUtil.getAddressByIP(ToolUtil.getClientIp(request)); sysLog.setArea(map.get("area")); sysLog.setProvince(map.get("province")); sysLog.setCity(map.get("city")); sysLog.setIsp(map.get("isp")); } sysLog.setType(ToolUtil.isAjax(request)?"Ajax請求":"普通請求"); sysLog.setUsername("自定義用戶"); } @Around("webLog()") public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { try { Object obj = proceedingJoinPoint.proceed(); return obj; } catch (Exception e) { e.printStackTrace(); sysLog.setException(e.getMessage()); throw e; } } @AfterReturning(returning = "ret", pointcut = "webLog()") public void doAfterReturning(Object ret) { sysLog.setUsername("自定義用戶"); String retString = JSONObject.toJSONString(ret); sysLog.setResponse(retString.length()>5000? JSONObject.toJSONString("請求參數數據過長不與顯示"):retString); sysLog.setUseTime(System.currentTimeMillis() - startTime.get()); sysLogService.save(sysLog); }}切面類里面設計到幾個工具類:
編程接口類
在項目里面新增測試接口類,在需要記錄日志的接口上面添加注解@SysLog,如下代碼:
package com.july.controller;import com.july.annotation.SysLog;import com.july.dto.UserLoginDto;import com.july.dto.UserRedisDto;import com.july.entity.Userinfo;import com.july.service.UserinfoService;import com.july.util.Result;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/** * 前端控制器 * @author zqk * @since 2019/12/4 */@RestController@RequestMapping("/userinfo")public class UserinfoController { @Resource private UserinfoService userinfoService; /** * @description 用戶登錄 * @param userLoginDto * @return * @author zqk * @since 2019/12/4 */ @SysLog("登錄") @PostMapping("/login") public Result login(@RequestBody UserLoginDto userLoginDto){ return Result.ok(userinfoService.userInfoLogin(userLoginDto)); }}接下來我們啟動項目,項目啟動成功后,訪問登錄接口,如下圖:
等接口響應成功后,我們打開數據庫去sys_log表里面查看記錄信息,記錄信息如下:
從數據庫記錄我們得知,接口調用的全部信息,這樣以來也方便開發人員排查操作記錄。對于上面的自定義注解記錄操作日志,大家覺得怎么樣啊?
總結
以上是生活随笔為你收集整理的slf4j注解log报错_SpringBoot自定义日志注解,用于数据库记录操作日志,你用过吗?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绿色的蜘蛛是什么品种 绿色的蜘蛛是哪个品
- 下一篇: 田园小院赚钱是真的吗(无锡田园东方)