基於aop進行springboot接口調用日誌和埋點日誌輸出,支持json格式方便elk收集

  • 基於nh-aop-logging
    添加了標記客戶端請求id:%X{ReqId} 須要設置filter
    方法執行時長:%X{elapsedTime}
    業務模塊標識: %X{bizModule} 須要設置@LogModule
    當前登陸用戶: %X{userId} 須要設置filter並實現userId獲取接口
    請求類: %X{callingClass}
    請求方法: %X{callingMethod}

引用jarjava

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

springboot工程中還應確保直接或間接引入了git

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

若是須要按照json輸出日誌還應引入github

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

初始化日誌aopspring

@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的獲取json

@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 設置業務模塊標識springboot

@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;
    }
}

日誌格式配置app

<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收集並分析接口日誌ide

<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綁定spring-boot

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

輸出效果url

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

相關文章
相關標籤/搜索