/nh-aop-logging

aop logging spring include bizid reqid callClass callmethod

Primary LanguageJavaApache License 2.0Apache-2.0


- 该项目基于aop-logging
添加了标记客户端请求id:%X{ReqId} 需要设置filter
方法执行时长:%X{elapsedTime}
业务模块标识: %X{bizModule} 需要设置@LogModule
当前登录用户: %X{userId} 需要设置filter并实现userId获取接口
请求类: %X{callingClass}
请求方法: %X{callingMethod}

引用jar

        <dependency>
            <groupId>com.github.jeffreyning</groupId>
            <artifactId>nh-aop-logging</artifactId>
            <version>1.0.1</version>
        </dependency>

springboot工程中还应确保直接或间接引入了

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

如果需要按照json输出日志还应引入

        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>5.0</version>
        </dependency>               

初始化日志aop

@Configuration
@EnableAspectJAutoProxy
public class LoggerConfig {

    private static final boolean SKIP_NULL_FIELDS = true;
    private static final int CROP_THRESHOLD = 7;
    private static final Set<String> EXCLUDE_SECURE_FIELD_NAMES = Collections.<String>emptySet();

    @Bean
    public AOPLogger getLoggerBean() {
        AOPLogger aopLogger = new AOPLogger();
        aopLogger.setLogAdapter(new UniversalLogAdapter(SKIP_NULL_FIELDS, CROP_THRESHOLD, EXCLUDE_SECURE_FIELD_NAMES));
        return aopLogger;
    }
}

初始化filter 注入自定义获取userId的实现类,支持ReqId和userId的获取

    @Bean
    public FilterRegistrationBean getDemoFilter() {
        ReqIdFilter reqIdFilter = new ReqIdFilter();
        reqIdFilter.setUserInfoLog(new UserInfoLog() {
            @Override
            public String getUserId() {
                //自定义获取userid的逻辑
                return "admin";
            }
        });
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(reqIdFilter);
        List<String> urlPatterns = new ArrayList<String>();
        urlPatterns.add("/*");
        registrationBean.setUrlPatterns(urlPatterns);
        registrationBean.setOrder(100);
        return registrationBean;
    }

在controller类上写入注解也可以写在方法上 @LogInfo 记录接口info日志 @LogException 记录接口异常日志 @LogModule 设置业务模块标识

@RestController
@RequestMapping("/test")
@LogInfo
@LogException
@LogModule("system")
public class TestCtl {

    @GetMapping("/query")
    public Map query(String echo){
        Map retMap=new HashMap();
        retMap.put("status",0);
        retMap.put("msg", "success");
        retMap.put("data", echo);
        return retMap;
    }

    @GetMapping("/createException")
    public Map createException(String echo){
        Map retMap=null;
        retMap.put("status",0);
        retMap.put("msg", "success");
        retMap.put("data", echo);
        return retMap;
    }
}

日志格式配置

	<appender name="interfaceConsole" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line]- class=%X{callingClass} method=%X{callingMethod} reqId=%X{reqId} userId=%X{userId} bizModule=%X{bizModule}  elapsedTime=%X{elapsedTime} - %msg%n</pattern>
			<charset>UTF-8</charset>
		</encoder>
	</appender>

按照json格式输出,方便elk收集并分析接口日志

	<appender name="interfaceLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${logFile}.interface</file>
		<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
			<providers>
				<pattern>
					<pattern>
						{
						"project": "log-demo",
						"timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}",
						"log_level": "%level",
						"thread": "%thread",
						"class_name": "%X{callingClass}",
						"class_method":"%X{callingMethod}",
						"message": "%message",
						"req_id": "%X{reqId}",
						"user_id": "%X{userId}",
						"biz_module": "%X{bizModule}",
                        "elapsedTime": "%X{elapsedTime}",
						"stack_trace": "%exception{5}"
						}
					</pattern>
				</pattern>
			</providers>
		</encoder>
		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
			<level>INFO</level>
		</filter>
		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
			<fileNamePattern>${logFile}.interface.%d{yyyy-MM-dd}.%i</fileNamePattern>
			<maxFileSize>${maxFileSize}</maxFileSize>
			<maxHistory>${maxHistory}</maxHistory>
		</rollingPolicy>
	</appender>

配置内置loger与appender绑定

	<logger name="com.github.nickvl.xspring.core.log.aop.AOPLogger" level="INFO" additivity="false" >
		<appender-ref ref="interfaceLog"/>
		<appender-ref ref="interfaceConsole"/>
	</logger>

输出效果

2020-10-20 19:00:21.398 [http-nio-8080-exec-1] INFO  c.g.n.xspring.core.log.aop.AOPLogger [LogStrategy.java:184]- class=com.github.jeffreyning.demo.controller.TestCtl method=query reqId=5fbce7c52847c3398cb1c9d5 userId=admin bizModule=system  elapsedTime= - calling: query(echo=111)
2020-10-20 19:00:21.429 [http-nio-8080-exec-1] INFO  c.g.n.xspring.core.log.aop.AOPLogger [LogStrategy.java:189]- class=com.github.jeffreyning.demo.controller.TestCtl method=query reqId=5fbce7c52847c3398cb1c9d5 userId=admin bizModule=system  elapsedTime=31 - returning: query(1 arguments):HashMap[{msg=success,data=111,status=0}]

异常日志输出效果

2020-11-24 19:45:27.453 [http-nio-8080-exec-3] INFO  c.g.n.xspring.core.log.aop.AOPLogger [LogStrategy.java:184]- class=com.github.jeffreyning.demo.controller.TestCtl method=createException reqId=5fbcf2576d198936a07e718d userId=admin bizModule=system elapsedTime= - calling: createException(echo=NIL)
2020-11-24 19:45:27.457 [http-nio-8080-exec-3] ERROR c.g.n.xspring.core.log.aop.AOPLogger [LogStrategy.java:125]- class=com.github.jeffreyning.demo.controller.TestCtl method=createException reqId=5fbcf2576d198936a07e718d userId=admin bizModule=system elapsedTime=0 - throwing: createException(1 arguments):class java.lang.NullPointerException

json日志输出效果

{"project":"log-demo","timestamp":"2020-11-24T19:40:57,433+0800","log_level":"INFO","thread":"http-nio-8080-exec-1","class_name":"com.github.jeffreyning.demo.controller.TestCtl","class_method":"query","line_number":"184","message":"calling: query(echo=111)","req_id":"5fbcf1496d198936a07e718c","user_id":"admin","biz_module":"system","elapsedTime":"","stack_trace":""}
{"project":"log-demo","timestamp":"2020-11-24T19:40:57,473+0800","log_level":"INFO","thread":"http-nio-8080-exec-1","class_name":"com.github.jeffreyning.demo.controller.TestCtl","class_method":"query","line_number":"189","message":"returning: query(1 arguments):HashMap[{msg=success,data=111,status=0}]","req_id":"5fbcf1496d198936a07e718c","user_id":"admin","biz_module":"system","elapsedTime":"24","stack_trace":""}

demo演示工程下载地址 https://pan.baidu.com/s/1zA6urPr3nbsnYY2UOCu9Iw 扫码订阅爱开发公众号,回复"log"获取下载密码 Image text