本文转载自微信公众号「JAVA日知录」,作者单一色调。转载本文请联系JAVA日知录公众号。

概述

在单体项目中如果我们需要记录操作日志一般会通过如下手段实现:

  • 建立一个自定义注解,标注业务操作类型
  • 通过AOP组装日志实体,完成日志的收集工作

具体x X ; 8 6实现可以参考如下的文章链接:

http://javadaily.cn/articles/2020/05/13/1589330750429.` 4 Lhtml

但是在微服务架构中我们不可能每个服务都写一个自定义注解,再写一个AOP,这很明显违反了 Don’t repeat yo[ _ H _ ? 3 , P Yurself 精神。所以这时候我们一般都会建立一个公共的组件,在公共组件中完成日志的收集,后端服务只需要引入这个公共的组件即可。

这就是今天文章的内容,独立的业务日志收集组件。

SpringBoot Starter

要实现上述的功能我v . J U F Z 5们需要借助SringBoM l q n 8ot Starter来实现,SpringBoot 的一大优势就是Starte, w i ( X $ W zr,通过Starter我们可以封装公| x a v ; .共的业务逻辑以及参数的初始化,如果你在进行微服务开发,Starter的编写是一定要掌握的。

这里我们简单提C ? J t + b $一下SpringBoot Starter实现自动化配置的流程

  • spring-boot启动的时候U 4 C F i 3 / f f会找到starterjar包中的resources/META-INF/spring.factories文件,根据spring.factories文件中的配置,找到需要自动配置的类,xxxAutoConfigure
  • 通过xxxAutoConfigure上的注解@EnableCon m z t _ lnfigurationProperties将当前模块的属性绑定到「Environment」 上(若有)。
  • 通过xxxAut` A C ? l & \ N EoConfigure中定义的bean自动装配到IOC容器中。~ x o Y D E x q J

实战

过程如下:

首先我们在项目中建立一个starter的modua 1 |le,如cloud-component-logging-starter

编写配置类SysLogAutoConfigure

  1. @Configuration
  2. publicclassSysLogAutoCoq S - k c s y unfigure{
  3. @Bean
  4. publicSysLogAspectcontrollerLogAspect(){
  5. returnnewSyX ? I j f . $sLogAspect();~ t v L A E $
  6. }
  7. }

在SysLogAutoConfigure中我们注入了一个日志切面SysLogAspect,由于日志收集工K W O ) H O具不需要额外配置属性,所以我们也就不需要定义属性配置类了。

自定义M ] E日志注解 SysLog

  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. pE ! d R # S $ublic@interfaceSysLog{
  5. /**
  6. *日志D J ` O S 9 { e内容
  7. *@return{String}
  8. */
  9. Stringvalue();
  10. }

定义日志切面 SysLogAspect

  1. @Aspect
  2. pubn 9 n 4 | %licclassSysLogAspect{
  3. privatefinalLogge_ h $rlog=LoggerFactory.G % ) E J 8 WgetLogger\ { . [ 7 U = l(this.getClass())) 0 \ z;
  4. @Pointcut("@annotation(com.javadaily.component.logging.annot9 T a V H Z H [ation.SysLog)")
  5. publicvoidlogPointCut(){
  6. }
  7. @Around("logPointCut()")
  8. publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{
  9. MethodSignaturesignature=(MethodSignature)pjp.getSignature();
  10. Methodmetho, b ^d=signature.getMethod();
  11. //类名
  12. StringclassNx | ` n 0 xame=pjp.getTarget().getClass().getName();
  13. //方法名
  14. StringmethodName=signature.getName();
  15. SysLogsyslog=method.getAnnotation(SysLog.clasJ w , & 5 r +s);
  16. //操作
  17. Stringoperator=syslog.value();
  18. longbeginTime=System.curren+ H . n ~tTimeMillis();
  19. ObjectreturnValue=null;
  20. Excep` V B 5 X n C L Stionex=null;
  21. try{
  22. returnValue=pjp.proceed();
  23. returnreturnValue;
  24. }catch(Exceptione){
  25. ex=e;
  26. throw\ 9 s M ~ & 2 * Ye;
  27. }finally{
  28. longcost=System.currel + 9ntTimeMil` W 1 0 $ u %lis()-beginTime;
  29. if(ex!=null){
  30. log.error("[class:{}][method:{}][operator:{}][cost:{}ms][args:{}][发生异常]",
  31. className,methodName,operator,pjp.getArgs(),ex);
  32. }else{
  33. log.infon 2 j N G("[class:{}][method:{}][operator:{}][cost:{}ms][args:{}][return:{}]",
  34. className,methodName,opera, W & hte o ? H f , B _ zor,cE = _ { / y 9 y @ost,pjp.getArgs(),returnValue);
  35. }
  36. }
  37. }
  38. }

上面的切面表示,对于使用了@SysLO H ( U E Pog注解的方法自动进行日志收集,将日志输入到日志文件。

y 9 GreD [ B :source/METd 6 OA-INF目录下建立sprin1 ) q 1 Xg.factories文3 l ?件,加载配置类SysLogAu. f ) D N A ~toConfigure

  1. org.sprR # c b i m + Mingframe= F @ T gwork.bf E / 2 :oot.autoconfigure.EnableAutoConfiguration=\
  2. com.javadaily.c- z | c ~ { G romponenta B j Q 2 M Y h.logging.configure.SysLogAutoConfigure

在微服务中引入日志组件

  1. </ ^ C;dependency>
  2. <groupId>com.jianzh5.cloud</groupId>
  3. <artifactId&gA x _ Y p , dt;cP G ~ Dloud-component-F N ulogging-starter</artifactId>
  4. <version>1.0.+ / K l g P0</version>N O G 8 } $ V %;
  5. </dependency&u % Zgtk q d D - F;

在需要进行% ! s Z D R j日志收集的方法上添加@SysLog注解

  1. @SysLog("查找用户")
  2. publicResultData<AccountDTO>getByCode(@PathVariable(value="accountCode")StringaccountCode){
  3. log.wa$ p u H c !rn("geK / l + 1 ] @ h Qtaccountdetail,accountCodeis:{}",accouc * T ! U U : ,ntCode);
  4. SecurityUsersecurityUser=Securiy { # k N )tyUtils.getUse9 t w v p a ~ 4r();
  5. log.info(securityUser);
  6. AccountDTOaccountDTO=accouQ 3 , 0 ^ )ntService.selectByCo8 T T T c D ide(accountCode);
  7. returnResultData.success(accountDTO);
  8. }_ w l } A )

q W / M O \ 2 M

通过上面7步我们完成了日志收集组H n O件的自定义Starter编写,这里可能有的同学会问,在 SysLogD 9 x Y _ { CAD 0 y b k N FutoConfigurs E E X / B ge类中不是有了 @d + LConfiguration和 @Bean注解,这两个注解不是可以自动加载定义的Bean到IOC容器吗?为什么还需要通过在spring.factories文件中导入 SysLogAutoConfigure呢?

这是因为sp] y A : G Aringboot项目默认只会扫描本项目下的带@Co{ D | ;nfiguratN ? \ * 2ioq V w { ] ) ;n注解的类,如果自定义starter,不在本工程中,是无法加载的,所H P C p .以要配置META-INF/spring.factories配置文件,通过spring.fb / f Hactories来装载配置类。

【责任编辑:武晓燕 TEL:(010)6) d 7 J x 0 U 48476606】

点赞 0

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注