SpringBoot日志收集-Aop方式-存进数据库一起来和我看看咋收集日志吧!!
現(xiàn)在大多數(shù)項(xiàng)目都會(huì)輸出日志或保存日志,現(xiàn)在這個(gè)大數(shù)據(jù)時(shí)代,數(shù)據(jù)已經(jīng)是一種非常非常重要的資源了。
日志也有很大作用的,不要小瞧它哦。😁
很喜歡一句話:“八小時(shí)內(nèi)謀生活,八小時(shí)外謀發(fā)展”。
如果你也喜歡,讓我們一起堅(jiān)持吧!!
共勉😁
我們:待別日相見時(shí),都已有所成
SpringBoot日志收集-Aop方式-存進(jìn)數(shù)據(jù)庫
- 一、前言
- 1)概述:
- 2)介紹:
- 3)使用場(chǎng)景:
- 二、前期準(zhǔn)備
- 2.1、數(shù)據(jù)庫
- 2.2、導(dǎo)入依賴
- 2.3、yml配置文件
- 2.3、配置自定義log注解類
- 2.4、SysLogAspect:切面處理類
- 2.5、MybatisPlus相關(guān)配置類
- 2.6、IpUtils
- 三、業(yè)務(wù)代碼
- 1、entity
- 2、mapper
- 3、Service
- 4、Controller
- 5、測(cè)試
- 四、自言自語
一、前言
本文使用的SpringBoot版本為:2.5.2
1)概述:
日志:網(wǎng)絡(luò)設(shè)備、系統(tǒng)及服務(wù)程序等,在運(yùn)作時(shí)都會(huì)產(chǎn)生一個(gè)叫l(wèi)og的事件記錄;每一行日志都記載著日期、時(shí)間、使用者及動(dòng)作等相關(guān)操作的描述。
2)介紹:
Windows網(wǎng)絡(luò)操作系統(tǒng)設(shè)計(jì)有各種各樣的日志文件,如應(yīng)用程序日志,安全日志、系統(tǒng)日志、Scheduler服務(wù)日志、FTP日志、WWW日志、DNS服務(wù)器日志等等,這些根據(jù)你的系統(tǒng)開啟的服務(wù)的不同而有所不同。
本文介紹的更多的是偏向于行為日志,并非系統(tǒng)日志級(jí)別的。
我們?cè)谙到y(tǒng)上進(jìn)行一些操作時(shí),這些日志文件通常會(huì)記錄下我們操作的一些相關(guān)內(nèi)容,這些內(nèi)容也許對(duì)我們來說并沒有什么用處,但是對(duì)系統(tǒng)安全工作人員卻相當(dāng)有用。
比如說有人對(duì)系統(tǒng)進(jìn)行了IPC探測(cè),系統(tǒng)就會(huì)在安全日志里迅速地記下探測(cè)者探測(cè)時(shí)所用的IP、時(shí)間、用戶名等,用FTP探測(cè)后,就會(huì)在FTP日志中記下IP、時(shí)間、探測(cè)所用的用戶名等。
3)使用場(chǎng)景:
簡(jiǎn)單介紹幾個(gè)~~(我還菜很多不曉得,狗頭保命😂)~~
對(duì)了哈,本文更多的是提供一個(gè)方法、思路和用一個(gè)完整案例來讓大家對(duì)SpringBoot-注解Aop記錄日志有一個(gè)認(rèn)識(shí)
二、前期準(zhǔn)備
案例:
使用SpringBoot的Aop方式,將訪問者的信息寫入數(shù)據(jù)庫中。
項(xiàng)目結(jié)構(gòu):
說明:因?yàn)榱?xí)慣了用MybatisPlus,拿了之前的完整配置,所以看起來java文件有多,但是關(guān)于log的其實(shí)并不復(fù)雜,代碼中也帶有注釋, 請(qǐng)放心食用。
對(duì)MybatisPlus感興趣的可以點(diǎn)👉SpringBoot整合MybatisPlus
2.1、數(shù)據(jù)庫
tb_user表
CREATE TABLE `tb_user` (`id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`passwrod` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`deleted` int(1) NOT NULL DEFAULT 0,`create_time` datetime(0) NOT NULL COMMENT '創(chuàng)建時(shí)間',`update_time` datetime(0) NOT NULL COMMENT '修改時(shí)間',PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;INSERT INTO `tb_user` VALUES ('1', '寧在春', '123456', 0, '2021-07-23 14:32:46', '2021-07-29 23:56:10'); INSERT INTO `tb_user` VALUES ('2', '青冬栗', 'qwerasd', 0, '2021-07-23 15:02:02', '2021-07-23 15:49:55');tb_log表
DROP TABLE IF EXISTS `tb_log`; CREATE TABLE `tb_log` (`id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`user_id` int(10) NOT NULL,`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`login_ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`type` int(10) NOT NULL,`url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`operation` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`create_time` datetime(0) NULL DEFAULT NULL,`remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '',`update_time` datetime(0) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;INSERT INTO `tb_log` VALUES ('e5b49465-b20a-453f-b15c-b284733f2f8e', 1, '寧在春', '0:0:0:0:0:0:0:1', 1, '127.0.0.1', '查詢用戶信息', '2021-08-15 01:04:31', '', '2021-08-15 01:04:31');2.2、導(dǎo)入依賴
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/> <!-- lookup parent from repository --> </parent> <dependencies><!--spring切面aop依賴--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.6</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.72</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.5</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency> </dependencies>依賴都是常用的哈,沒啥要說的哈。😀
2.3、yml配置文件
server:port: 8091 spring:application:name: springboot-log# 數(shù)據(jù)源配置datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driver# 阿里的數(shù)據(jù)庫連接池druid:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/commons_utils?serverTimezone=UTC&useSSL=false&characterEncoding=utf8&serverTimezone=GMT# 初使化連接數(shù)(向數(shù)據(jù)庫要五個(gè)連接)initial-size: 5# 最小連接數(shù)(常住10個(gè)連接)min-idle: 10# 最大連接數(shù)(最多獲得10個(gè)連接,多到10個(gè)數(shù)據(jù)庫將進(jìn)入一個(gè)阻塞狀態(tài),等待其他連接釋放)max-active: 20# 獲取連接最長(zhǎng)等待時(shí)間,單位毫秒max-wait: 10000# 配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒minEvictableIdleTimeMillis: 300000# 配置一個(gè)連接在池中最大生存的時(shí)間,單位是毫秒maxEvictableIdleTimeMillis: 900000jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8 mybatis-plus:configuration:cache-enabled: true #開啟緩存log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #開啟sql日志mapper-locations: classpath:/mapper/*Mapper.xmlglobal-config:db-config:logic-delete-field: flag # 全局邏輯刪除的實(shí)體字段名(since 3.3.0,配置后可以忽略不配置步驟2)logic-delete-value: 1 # 邏輯已刪除值(默認(rèn)為 1)logic-not-delete-value: 0 # 邏輯未刪除值(默認(rèn)為 0)2.3、配置自定義log注解類
如果需要收集多種日志的話,可以做擴(kuò)展,增加注解也可,用編碼也可,當(dāng)然如果項(xiàng)目多的話,那么必然是要抽取出來才是最合適的。
(經(jīng)驗(yàn)不足、如有不妥,請(qǐng)及時(shí)提出,蟹蟹各位大佬😁)
/*** 配置自定義log注解類* @author crush*/ @Target(ElementType.METHOD) //注解放置的目標(biāo)位置,METHOD是可注解在方法級(jí)別上 @Retention(RetentionPolicy.RUNTIME) //注解在哪個(gè)階段執(zhí)行 @Documented //生成文檔 public @interface MyLog {/** 操作事件 */String operation () default "";/** 日志類型 */int type (); }2.4、SysLogAspect:切面處理類
import cn.hutool.core.lang.UUID; import com.crush.log.annotation.MyLog; import com.crush.log.entity.LogOperation; import com.crush.log.entity.LogUser; import com.crush.log.mapper.LogOperationMapper; import com.crush.log.utils.IpUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method;/** 系統(tǒng)日志:切面處理類 */ @Aspect @Component public class SysLogAspect {/**我這里是使用log4j2把一些信息打印在控制臺(tái)上面,可以不寫 */private static final Logger log = LogManager.getLogger(SysLogAspect.class);/**操作數(shù)據(jù)庫 */@Autowiredprivate LogOperationMapper logOperationMapper;/*** 定義切點(diǎn) @Pointcut* 在注解的位置切入代碼* 這里的意思就是注解寫在那個(gè)方法上,那個(gè)方法就是被切入的。*/@Pointcut("@annotation(com.crush.log.annotation.MyLog)")public void logPoinCut() {}//切面 配置通知@Before("logPoinCut()") //AfterReturningpublic void saveOperation(JoinPoint joinPoint) {log.info("---------------接口日志記錄---------------");//用于保存日志LogOperation logOperation = new LogOperation();// 這里是獲得當(dāng)前請(qǐng)求的requestServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = servletRequestAttributes.getRequest();String requestURL = request.getRequestURL().toString();logOperation.setUrl(requestURL);// 客戶端ip 這里還可以與之前做一個(gè)比較,如果不同的話,就給他推送消息什么的,說異地登錄 什么的。 String ip = IpUtils.getIpAddr(request);logOperation.setLoginIp(ip);//從切面織入點(diǎn)處通過反射機(jī)制獲取織入點(diǎn)處的方法MethodSignature signature = (MethodSignature) joinPoint.getSignature();//獲取切入點(diǎn)所在的方法Method method = signature.getMethod();//獲取操作--方法上的Log的值MyLog myLog = method.getAnnotation(MyLog.class);if (myLog != null) {//保存操作事件String operation = myLog.operation();logOperation.setOperation(operation);//保存日志類型 這里也可以做擴(kuò)展 根據(jù)不同的類型,你可以做不同的操作 int type = myLog.type();logOperation.setType(type);log.info("operation="+operation+",type="+type);}// 操作人賬號(hào)、姓名(需要提前將用戶信息存到session)// 因?yàn)檫@里是模擬 所以偷懶用了個(gè) session // 實(shí)際上用了security 獲取的應(yīng)該是當(dāng)前授權(quán)對(duì)象的信息 而不是從session 中獲取 // 也或者說是從 redis 中獲取,這只是提供一個(gè)思路,請(qǐng)見諒LogUser user = (LogUser) request.getSession().getAttribute("user");if(user != null) {String userId = user.getId();String userName = user.getUsername();logOperation.setUserId(userId);logOperation.setUsername(userName);System.out.println(user);}log.info("url="+requestURL,"ip="+ip);//調(diào)用service保存Operation實(shí)體類到數(shù)據(jù)庫//我id使用的是UUID,不需要的可以注釋掉String id = UUID.randomUUID().toString().replace("-","");logOperation.setId(id);logOperationMapper.insert(logOperation);} }2.5、MybatisPlus相關(guān)配置類
MybatisPlusConfig
/*** @EnableTransactionManagement :開啟事務(wù)* @Author: crush* @Date: 2021-07-23 14:14* version 1.0*/ @Configuration @EnableTransactionManagement @MapperScan("com.crush.log.mapper") public class MybatisPlusConfig {/*** 分頁*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));// 注冊(cè)樂觀鎖 插件return mybatisPlusInterceptor;}/** 配置數(shù)據(jù)源 druid*/@Bean@Primary@ConfigurationProperties("spring.datasource.druid")public DruidDataSource druidDataSource() {return DruidDataSourceBuilder.create().build();} }MyMetaObjectHandler:自動(dòng)填充
/*** 填充創(chuàng)建和修改時(shí)間* @Author: crush* @Date: 2021-07-23 14:14*/ @Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("start insert fill ....");this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);this.setFieldValByName("updateTime",LocalDateTime.now(),metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {log.info("start update fill ....");this.setFieldValByName("updateTime",LocalDateTime.now(),metaObject);} }LocalDateTimeSerializerConfig:配置全局的LocalDateTime格式化
@Configuration public class LocalDateTimeSerializerConfig {@Value("${spring.jackson.date-format}")private String DATE_TIME_PATTERN;@Value("${spring.jackson.date-format}")private String DATE_PATTERN ;/*** string轉(zhuǎn)localdate*/@Beanpublic Converter<String, LocalDate> localDateConverter() {return new Converter<String, LocalDate>() {@Overridepublic LocalDate convert(String source) {if (source.trim().length() == 0) {return null;}try {return LocalDate.parse(source);} catch (Exception e) {return LocalDate.parse(source, DateTimeFormatter.ofPattern(DATE_PATTERN));}}};}/** * string轉(zhuǎn)localdatetime*/@Beanpublic Converter<String, LocalDateTime> localDateTimeConverter() {return new Converter<String, LocalDateTime>() {@Overridepublic LocalDateTime convert(String source) {if (source.trim().length() == 0) {return null;}// 先嘗試ISO格式: 2019-07-15T16:00:00try {return LocalDateTime.parse(source);} catch (Exception e) {return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DATE_TIME_PATTERN));}}};}/** * 統(tǒng)一配置 LocalDateTime 格式化*/@Beanpublic Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {JavaTimeModule module = new JavaTimeModule();LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));module.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);return builder -> {builder.simpleDateFormat(DATE_TIME_PATTERN);builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_PATTERN)));builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN)));builder.modules(module);};} }2.6、IpUtils
import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException;/*** 獲取IP方法*/ public class IpUtils {public static String getIpAddr(HttpServletRequest request){if (request == null){return "unknown";}String ip = request.getHeader("x-forwarded-for");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("X-Forwarded-For");}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("X-Real-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){ip = request.getRemoteAddr();}return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;}public static boolean internalIp(String ip){byte[] addr = textToNumericFormatV4(ip);return internalIp(addr) || "127.0.0.1".equals(ip);}private static boolean internalIp(byte[] addr){if (addr == null || addr.length < 2){return true;}final byte b0 = addr[0];final byte b1 = addr[1];// 10.x.x.x/8final byte SECTION_1 = 0x0A;// 172.16.x.x/12final byte SECTION_2 = (byte) 0xAC;final byte SECTION_3 = (byte) 0x10;final byte SECTION_4 = (byte) 0x1F;// 192.168.x.x/16final byte SECTION_5 = (byte) 0xC0;final byte SECTION_6 = (byte) 0xA8;switch (b0){case SECTION_1:return true;case SECTION_2:if (b1 >= SECTION_3 && b1 <= SECTION_4){return true;}case SECTION_5:if (b1 == SECTION_6) {return true;}default:return false;}}/*** 將IPv4地址轉(zhuǎn)換成字節(jié)* * @param text IPv4地址* @return byte 字節(jié)*/public static byte[] textToNumericFormatV4(String text){if (text.length() == 0){return null;}byte[] bytes = new byte[4];String[] elements = text.split("\\.", -1);try{long l;int i;switch (elements.length){case 1:l = Long.parseLong(elements[0]);if ((l < 0L) || (l > 4294967295L))return null;bytes[0] = (byte) (int) (l >> 24 & 0xFF);bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);bytes[3] = (byte) (int) (l & 0xFF);break;case 2:l = Integer.parseInt(elements[0]);if ((l < 0L) || (l > 255L))return null;bytes[0] = (byte) (int) (l & 0xFF);l = Integer.parseInt(elements[1]);if ((l < 0L) || (l > 16777215L))return null;bytes[1] = (byte) (int) (l >> 16 & 0xFF);bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);bytes[3] = (byte) (int) (l & 0xFF);break;case 3:for (i = 0; i < 2; ++i){l = Integer.parseInt(elements[i]);if ((l < 0L) || (l > 255L))return null;bytes[i] = (byte) (int) (l & 0xFF);}l = Integer.parseInt(elements[2]);if ((l < 0L) || (l > 65535L))return null;bytes[2] = (byte) (int) (l >> 8 & 0xFF);bytes[3] = (byte) (int) (l & 0xFF);break;case 4:for (i = 0; i < 4; ++i){l = Integer.parseInt(elements[i]);if ((l < 0L) || (l > 255L))return null;bytes[i] = (byte) (int) (l & 0xFF);}break;default:return null;}}catch (NumberFormatException e){return null;}return bytes;}public static String getHostIp(){try{return InetAddress.getLocalHost().getHostAddress();}catch (UnknownHostException ignored){}return "127.0.0.1";}public static String getHostName(){try{return InetAddress.getLocalHost().getHostName();}catch (UnknownHostException ignored) {}return "未知";} }三、業(yè)務(wù)代碼
我這里沒有寫查看日志的接口,存數(shù)據(jù)庫,管理員可以隨時(shí)查看這些信息,也可以使用web頁面、會(huì)方便許多。
1、entity
LogUser
/*** @Author: crush* @Date: 2021-08-14 8:43* version 1.0*/ @Data @Accessors(chain = true) @TableName("tb_user") public class LogUser implements Serializable {private static final long serialVersionUID = 1L;private String id;private String username;private String passwrod;/*** 邏輯刪除字段 */@TableLogicprivate Integer deleted;/*** 創(chuàng)建時(shí)間*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;/*** 修改時(shí)間*/@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime; } package com.crush.log.entity;import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Builder; import lombok.Data; import lombok.experimental.Accessors;import java.io.Serializable; import java.time.LocalDateTime;/*** 日志表* @author crush*/ @Data @Accessors(chain = true) @TableName("tb_log") public class LogOperation implements Serializable {private static final long serialVersionUID = 7925874058046995566L;private String id;/*** 用戶id 操作人ID */private String userId;/** * 用戶名稱 關(guān)聯(lián)admin_user */private String username;/** * 登錄ip */private String loginIp;/** * 操作類型(0登錄、1查詢、2修改) 這個(gè)根據(jù)自己需求定義即可 ,還有很多其他方式,這個(gè)并不完善,只是剛剛夠用的那種 */private int type;/** * 操作的url*/private String url;/** * 操作內(nèi)容 */private String operation;/** * 操作時(shí)間*/@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;/*** 備注*/private String remark;/*** 修改時(shí)間*/@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime; }2、mapper
@Repository @Mapper public interface LogOperationMapper extends BaseMapper<LogOperation> { } @Repository public interface LogUserMapper extends BaseMapper<LogUser> { }3、Service
public interface ILogUserService extends IService<LogUser> { } @Service public class LogUserServiceImpl extends ServiceImpl<LogUserMapper, LogUser> implements ILogUserService { }4、Controller
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.crush.log.annotation.MyLog; import com.crush.log.entity.LogUser; import com.crush.log.service.ILogUserService; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest; import java.util.List;@RestController @RequestMapping("user") public class UserController {private static final Logger log = LogManager.getLogger(UserController.class);@Autowiredprivate ILogUserService userService;/*** 假裝登錄,將用戶信息存到session(方法是我之前寫的懶得改,)* */@RequestMapping("/login")public String login(@RequestBody LogUser logUser,HttpServletRequest request){QueryWrapper<LogUser> wrapper = new QueryWrapper<>();wrapper.eq("username",logUser.getUsername()).eq("passwrod",logUser.getPasswrod());LogUser user = userService.getOne(wrapper);if(user!=null){request.getSession().setAttribute("user",user);return "登錄成功";}return "登錄失敗";}/**記錄日志*/@MyLog(operation = "查詢用戶信息",type = 1)@RequestMapping("/log")public List<LogUser> insertLog(HttpServletRequest request){List<LogUser> users = userService.list();return users;} }記得寫個(gè)主啟動(dòng)類,這我就不寫啦。
5、測(cè)試
直接啟動(dòng)測(cè)試,先登錄,再訪問/log.
再訪問/log
我們?cè)倏匆幌潞笈_(tái)輸出:
四、自言自語
本文只是給大家提供一個(gè)小思路,代碼寫的較為粗糙,請(qǐng)見諒。😁
還有很多地方可以擴(kuò)展和完善,大家感興趣的話,可以多試一試,這樣學(xué)習(xí)才有樂趣啦。😂
日志的話他還會(huì)分很多類的,大家可以根據(jù)自己的需求擴(kuò)展。
我知道咱們CSDN的大佬,講話又好聽,長(zhǎng)的又帥,女朋友隨便new,給小弟一個(gè)贊👍,這肯定的吧。😁
總結(jié)
以上是生活随笔為你收集整理的SpringBoot日志收集-Aop方式-存进数据库一起来和我看看咋收集日志吧!!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot整合异步任务实现发送
- 下一篇: 今天,我们来详细的聊一聊SpringBo