范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

SpringCloud使用注解AOPMQ来实现日志管理模块

  简介
  无论在什么系统中,日志管理模块都属于十分重要的部分,接下来会通过注解+AOP+MQ的方式实现一个简易的日志管理系统  思路注解:  标记需要记录日志的方法  AOP:  通过AOP增强代码,利用后置/异常通知的方式获取相关日志信息,最后使用MQ将日志信息发送到专门处理日志的系统  RabbitMQ:  利用解耦、异步的特性,协调完成各个微服务系统之间的通信  1、日志表结构
  表结构(sys_log):  CREATE TABLE `sys_log` (   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT "唯一ID",   `opt_id` int(11) DEFAULT NULL COMMENT "操作用户id",   `opt_name` varchar(50) DEFAULT NULL COMMENT "操作用户名",   `log_type` varchar(20) DEFAULT NULL COMMENT "日志类型",   `log_message` varchar(255) DEFAULT NULL COMMENT "日志信息(具体方法名)",   `create_time` datetime DEFAULT NULL COMMENT "创建时间",   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COMMENT="系统日志表";
  实体类(SysLog):  @Data public class SysLog  {       private static final long serialVersionUID = 1L;       /**      * 唯一ID      */     @TableId(value = "id", type = IdType.AUTO)     private Integer id;     /**      * 操作用户id      */     private Integer optId;     /**      * 操作用户名      */     private String optName;     /**      * 日志类型      */     private String logType;     /**      * 日志信息(具体方法名)      */     private String logMessage;     /**      * 创建时间      */     private Date createTime;   } 2、注解注解(SystemLog):
  仅作为标记的作用,目的让JVM可以识别,然后可以从中获取相关信息  @Target:  定义注解作用的范围,这里是方法  @Retention:  定义注解生命周期,这里是运行时  @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SystemLog {       SystemLogEnum type();   } 枚举(SystemLogEnum):
  限定日志类型范围  public enum SystemLogEnum {       SAVE_LOG("保存"),     DELETE_LOG("删除"),     REGISTER_LOG("注册"),     LOGIN_LOG("登录"),     LAUD_LOG("点赞"),     COLLECT_LOG("收藏"),     THROW_LOG("异常"),     ;     private String type;       SystemLogEnum(String type) {         this.type = type;     }       public String getType() {         return type;     } } 3、AOP切面AOP(SysLogAspect):
  实现代码的增强,主要通过动态代理方式实现的代码增强。拦截注解,并获取拦截到的相关信息,封装成日志对象发送到MQ队列(生产端)  Component @Aspect @Slf4j public class SysLogAspect {       @Autowired     MqStream stream;       //切点     @Pointcut("@annotation(cn.zdxh.commons.utils.SystemLog)")     public void logPointcut(){}       //后置通知     @After("logPointcut()")     public void afterLog(JoinPoint joinPoint) {         //一般日志         SysLog sysLog = wrapSysLog(joinPoint);           log.info("Log值:"+sysLog);           //发送mq消息         stream.logOutput().send(MessageBuilder.withPayload(sysLog).build());       }       //异常通知     @AfterThrowing(value = "logPointcut()", throwing = "e")     public void throwingLog(JoinPoint joinPoint, Exception e) {         //异常日志         SysLog sysLog = wrapSysLog(joinPoint);         sysLog.setLogType(SystemLogEnum.THROW_LOG.getType());         sysLog.setLogMessage(sysLog.getLogMessage()+"==="+e);           log.info("异常Log值:"+sysLog);           //发送mq消息         stream.logOutput().send(MessageBuilder.withPayload(sysLog).build());     }       /**      * 封装SysLog对象      * @param joinPoint      * @return      */     public SysLog wrapSysLog(JoinPoint joinPoint){         //获取请求响应对象         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();         HttpServletRequest request = attributes.getRequest();         MethodSignature signature = (MethodSignature)joinPoint.getSignature();         SysLog sysLog = new SysLog();           //获取方法全路径         String methodName = signature.getDeclaringTypeName()+"."+signature.getName();         //获取注解参数值         SystemLog systemLog = signature.getMethod().getAnnotation(SystemLog.class);         //从header取出token         String token = request.getHeader("token");         if (!StringUtils.isEmpty(token)) {             //操作人信息             Integer userId = JwtUtils.getUserId(token);             String username = JwtUtils.getUsername(token);             sysLog.setOptId(userId);             sysLog.setOptName(username);         }         if (!StringUtils.isEmpty(systemLog.type())){             sysLog.setLogType(systemLog.type().getType());         }         sysLog.setLogMessage(methodName);         sysLog.setCreateTime(new Date());         return sysLog;     }   } 3、RabbitMQ消息队列MQ:
  这里主要是通过Spring Cloud Stream集成的RabbitMQ  Spring Cloud Stream:
  作为MQ的抽象层,已屏蔽各种MQ的各自名词,统称为input、output两大块。可以更方便灵活地切换各种MQ,如 kafka、RocketMQ等
  (1)定义Input/Ouput接口(MqStream)@Component public interface MqStream {       String LOG_INPUT = "log_input";       String LOG_OUTPUT = "log_output";        @Input(LOG_INPUT)     SubscribableChannel logInput();       @Output(LOG_OUTPUT)     MessageChannel logOutput();   } (2)MQ生产者
  注:这里使用到AOP切面的微服务,都属于MQ生产者服务
  引入依赖:
  这里没有版本号的原因是spring cloud已经帮我们管理好各个版本号,已无需手动定义版本号        org.springframework.cloud      spring-cloud-stream       org.springframework.cloud     spring-cloud-stream-binder-rabbit 
  在程序入口开启MQ的Input/Output绑定:  @SpringBootApplication(scanBasePackages = {"cn.zdxh.user","cn.zdxh.commons"}) @EnableEurekaClient @MapperScan("cn.zdxh.user.mapper") @EnableBinding(MqStream.class) //开启绑定 @EnableFeignClients  public class YouquServiceProviderUserApplication {       public static void main(String[] args) {         SpringApplication.run(YouquServiceProviderUserApplication.class, args);     }   }
  yml配置:
  在生产者端设置output  destination:  相当于rabbitmq 的exchange  group:  相当于rabbitmq的queue ,不过是和destination 一起组合成的queue名 binder:  需要绑定的MQ  #Spring Cloud Stream相关配置 spring:   cloud:     stream:       bindings: # exchange与queue绑定         log_output: # 日志生产者设置output           destination: log.exchange           content-type: application/json           group: log.queue           binder: youqu_rabbit #自定义名称       binders:         youqu_rabbit:  #自定义名称           type: rabbit           environment:             spring:               rabbitmq:                 host: localhost                 port: 5672                 username: guest                 password: 25802580
  注:完成以上操作,即完成MQ生产端的所有工作   (3)MQ消费者
  引入依赖、开启Input/Output绑定:均和生产者的设置一致
  yml配置:
  在生产者端设置input  spring:   cloud:  # Spring Cloud Stream 相关配置     stream:       bindings: # exchange与queue绑定         log_input: # 日志消费者设置input           destination: log.exchange           content-type: application/json           group: log.queue           binder: youqu_rabbit       binders:         youqu_rabbit:           type: rabbit           environment:             spring:               rabbitmq:                 host: localhost                 port: 5672                 username: guest                 password: 25802580
  消费者监听(LogMqListener):
  监听生产者发过来的日志信息,将信息添加到数据库即可  @Service @Slf4j public class LogMqListener {       @Autowired     SysLogService sysLogService;       @StreamListener(MqStream.LOG_INPUT)     public void input(SysLog sysLog)  {         log.info("开始记录日志========================");           sysLogService.save(sysLog);           log.info("结束记录日志========================");       } }
  注:完成以上操作,即完成MQ消费端的所有工作   4、应用
  简述:
  只需将 @SystemLog(type = SystemLogEnum.REGISTER_LOG) ,标记在需要记录的方法上,当有客户端访问该方法时,就可以自动完成日志的记录
  5、总结
  流程:
  注解标记--->AOP拦截--->日志发送到MQ--->专门处理日志的系统监听MQ消息 --->日志插入到数据库
  来源:blog.csdn.net/weixin_38802061/article/details/105458047

想见你导演微博关注吴磊赵今麦影迷期待合作1905电影网讯1月11日,有网友发现,电影想见你的导演黄天仁已经在微博关注了吴磊和赵今麦两位青年演员。2019年,由黄天仁作为导演推出的剧集想见你在播出后获得大量好评。时隔3年,我国高等教育进入普及化阶段中国矿业大学硕士毕业生赵彬宇登上列车,前往内蒙古霍林河南露天矿就业,立志为高寒地区绿色矿山建设贡献力量北京电子科技职业学院汽车工程学院的实训室里,新能源汽车技术专业学生李新海正在研家门口建起数字补给站,让老年人不再拿着手机犯难快帮我看看,手机怎么黑屏了?听邻居说,现在网上点餐比店里买还便宜,是真的吗?早上六点起来就往医院跑,怎么还是挂不上号?近年来,随着数字技术的飞速发展,很多老年人都用上了智能手机平板微软已终止对Windows8。1的支持,并建议用户进行升级微软近日宣布,对Windows8。1的支持将会在2023年1月10日结束,所有运行Windows8。1的PC将不会从微软这里得到任何问题的技术支持,软件更新和补丁。在通告里面微软还为什么说电子游戏产业一定会越来越兴盛?齐大圣论道线下互联网咖啡早安,在听鸟叫晨醒的上海问候各位抱拳电子游戏下一代俄乌战事中无人机和相关应用的战果让大家对于电子游戏有了全新的认识,这个原来被认为丧志的玩物忽然有了全新的意苹果再次砍单2023年消费电子市场前景如何哔哥哔特导读今年刚开年苹果三大产品线遭砍单,短期内消费电子市场依旧难掩颓势。在突破瓶颈和困难上,手机厂商们任重道远。近日,苹果再次传出砍单消息。据日经新闻报道,苹果以需求减弱为由,独家微信回应切断抖音外链坚决打击给用户造成诱导骚扰的字符口令1月10日晚间,第一财经独家报道抖音链接目前在微信内既无法直接打开也无法复制完成跳转,甚至要通过图片OCR识别进行文字提取的情况。但微信内淘宝链接仍可进行复制,完成在淘宝内的链接跳望尘科技将上市,贾小东靠游戏半年收入3亿,充值问题遭用户投诉出品子弹财观1月11日消息,望尘科技控股有限公司在2022年12月28日通过港交所聆讯,并在12月30日开启招股,他们预计将在1月16日正式上市。据望尘科技聆讯后的招股书显示,他们安息吧,爸爸!我们来生再见!当我们一起冲过终点后你却倒在了线上。从12月20号过来陪你至今,那么多年来第一次感觉角色互换。以前大多时候是你担心我的学习和工作,而现在是我担心你的健康和吃喝拉撒。每天24小时的时秦始皇的爷爷和父亲都离奇死亡,是巧合还是另有原因?秦始皇的祖父秦孝文帝在继位三天后去世,享年53岁。秦始皇的父亲秦壮乡在继位三年后去世,享年35岁。不管是53还是35,都不算长。他们都是怎么死的,史书上没有记载。没有历史记载,就会独自在家突遇大火,杭州8岁女孩冷静逃生,消防也给她点赞!这些做法值得和孩子分享近日,杭州市西溪实验学校二年级的一位班主任金老师收到家长发来的感谢信,家长在信中感谢学校平时教孩子遇到着火时的应急处理方法,让小朋友学会了在面对危险时应该如何逃生。孩子8岁,当时独
生态修复见成效越来越多珍稀动植物北海安家央视网消息随着生态环境逐步恢复,广西北海滨海国家湿地公园内的动物种类也在不断增加,近期更是首次记录到多种珍稀鸟类,再次刷新湿地鸟类物种的数据。近日,广西北海滨海国家湿地公园管理处监紫苏的营养成分紫苏全株均有很高的营养价值,它具有低糖高纤维高胡萝卜素高矿质元素等。紫苏叶片营养丰富,富含氨基酸,粗蛋白质等成分,是日本韩国等国家深受欢迎的保健蔬菜。紫苏茎叶具有特异芳香,并含有丰秋天吃梨好处多,快来看看梨的隐藏功效吧秋天红叶纷飞,大地一片金黄,各种果实收获,是大自然的馈赠,所以秋季是一个丰收喜悦的季节。但是,秋冬季节天气干燥,气温也逐渐下降,人体不一定能够承受的住,这大自然的馈赠。由于天气骤变如果人一辈子不吸烟不喝酒,会不会活得更久呢?医生告诉你真相2018年柳叶刀曾经发表过一项调查研究,结果显示喝酒直接导致280万人死亡,而我国是全球饮酒致死最多的国家,每年大约有70万国人因为喝酒丧命。世卫组织也已经将酒精列为一级致癌物,所23批次不合格化妆品被曝光,郁美净儿童霜玥之秘水晶防晒霜上黑榜10月25日,国家药监局通报了23批次化妆品(含牙膏)不符合规定。北京青年报记者注意到,标称郁美净儿童霜玥之秘水晶防晒喷雾等产品在不符合规定名单中。而被通报的玥之秘水晶防晒喷雾更是中国癌症高发,或是蚝油惹的祸吗?医生这3种调味品,建议少吃现代生活水平的不断提高,人们的饮食习惯也随着改变。正所谓民以食为天,饮食在我们中国人看来是最重要的一件事。我国人民对于饮食的需求也随着生活水平的提高而提高,色香味俱全的美食,离不开一条没有归期的路鲁迅先生说其实这地上本没有路,走的人多了,也便成了路。我家门前的路,就是这样走出来的。最初是一条弯弯曲曲的羊肠小道,因着它是离公路最近的一条道,随着人越走越多,便成了路,渐渐地宽阔趁清闲把心里的垃圾情绪倒一倒居家足不出户十几天了,一点小事都会郁闷很久,心绪总是起伏不定,工作的事儿,生活的事儿交织缠绕。古人云心大则百物皆通,心小则百物皆病。人心如果宽了,什么都能看得开若小了,看什么都会是请远离垃圾人,他们会重新编码您的大脑,把您拖入他们的悲惨世界1垃圾人会编码您的大脑我分享智慧,不是为了和凡夫们讨论和争辩,因为凡夫没有参与讨论的知识积累。随便张嘴和我讨论的人,我不会理会,巧舌如簧刻意找理由反对我的人更不必说,直接拉黑。我没家有孩子,这3种垃圾食品要少买!不妨自己在家做,营养又健康秋日生活打卡季不仅小朋友对零食没有抵抗力,即使大人遇见好吃的零食也爱不释口。现如今生活条件变好了,琳琅满目的零食让人眼花缭乱。但在满足口舌之欲的同时,也会对我们的身体埋下隐患,所以为什么要有点文化你问我为什么要有点文化,回答这个问题或许要长篇大论,或许要引经据典,或许要滔滔不绝,或许要娓娓道来。但其实,人之所以要有点文化,是尊重内心的一种取向而已,是对人生在世的一种诠释,是