java annotation combined with spring aop to automatically output logs and add interceptors and filters

auto-log

auto-log Is an automatic log monitoring framework designed for java.

I have already written two articles:

Realize the automatic output of spring annotation combined with java spring

java annotation combined with spring aop to realize the unique identification of log traceId

After the code implementation of the previous two articles, it is found that the following problems still exist:

(1) The use of annotations is still not convenient enough.

If @ AutoLog is specified on each method, it will still be troublesome. I don't want to be so troublesome when I use it.

So I want to add class based annotations.

In the later stage, it is considered whether the scanning package range of AOP can be dynamically specified based on the package.

(2) The processing of logs is too simple.

For example, I want to add the audit logs of all operations and store them in the database. At the same time, the log output remains unchanged.

It is found that the previous log framework cannot be well supported. So I want to add an interceptor for log output.

(3) Filtering of parameters

In the past, it was implemented directly based on toString(). It was found that some people are lazy and don't write toString (such as me), so the information printed by parameters is meaningless.

Therefore, FastJSON is established instead, but it leads to new problems. For example, direct serialization of parameters such as HttpRequest will report errors, so I want to add a parameter based filter implementation.

Demand is the best creative power.

At present, a total of 12 versions have been iterated, and the above three features have been met.

characteristic

  • Flexible configuration based on annotation + bytecode
  • Automatically adapt to common logging frameworks
  • Support programmatic call
  • Support annotation and perfect integration of spring
  • Support the integration of spring boot
  • Support slow log threshold specification, time-consuming, input parameter, output parameter, exception information and other common attribute specification
  • traceId attribute supported
  • Support class level definition annotation
  • Supports custom interceptors and filters

Quick start

maven introduction

<dependency>
    <group>com.github.houbb</group>
    <artifact>auto-log-core</artifact>
    <version>${Latest version}</version>
</dependency>

Introductory case

UserService userService = AutoLogHelper.proxy(new UserServiceImpl());
userService.queryLog("1");
  • The log is as follows
[INFO] [2020-05-29 16:24:06.227] [main] [c.g.h.a.l.c.s.i.AutoLogMethodInterceptor.invoke] - public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) param is [1]
[INFO] [2020-05-29 16:24:06.228] [main] [c.g.h.a.l.c.s.i.AutoLogMethodInterceptor.invoke] - public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) result is result-1

code

The method is as follows:

  • UserService.java
public interface UserService {

    String queryLog(final String id);

}
  • UserServiceImpl.java

Directly use the annotation @ AutoLog to specify the method of logging.

public class UserServiceImpl implements UserService {

    @Override
    @AutoLog
    public String queryLog(String id) {
        return "result-"+id;
    }

}

Example of TraceId

code

UserService service =  AutoLogProxy.getProxy(new UserServiceImpl());
service.traceId("1");

The traceId method is as follows:

@AutoLog
@TraceId
public String traceId(String id) {
    return id+"-1";
}

Test effect

information: [ba7ddaded5a644e5a58fbd276b6657af] <traceId>Enter reference: [1].
information: [ba7ddaded5a644e5a58fbd276b6657af] <traceId>Output reference: 1-1.

Where ba7ddaded5a644e5a58fbd276b6657af is the corresponding traceId, which can run through the whole thread cycle to facilitate our log viewing.

Notes

@AutoLog

The attributes of the core annotation @ AutoLog are described as follows:

attribute type Default value explain
enable boolean true Enable
param boolean true Print in parameters
result boolean true Print out parameters
costTime boolean false Print time consuming
exception boolean true Print exception
slowThresholdMills long -1 When this value is greater than or equal to 0 and the time consumption exceeds the configured value, the slow log will be output
description string "" Method description. Method name is selected by default
interceptor Class[] Default implementation Interceptor implementation, which supports specifying multiple and customizing
paramFilter Class empty Input parameter filter, support customization

@TraceId

@traceId is placed on the method that needs to set traceId, such as Controller layer, mq consumer, receiver of rpc request, etc.

attribute type Default value explain
id Class The default is uuid Implementation strategy of traceId
putIfAbsent boolean false Whether to set the value only when the current thread has no value
enable boolean true Enable
interceptor Class[] Default implementation Interceptor implementation, supporting specifying multiple and customizing

Custom policy

Custom log interceptor

Built in interceptor

AutoLogInterceptor default implementation

definition

Directly inherit from AbstractAutoLogInterceptor class and implement corresponding methods.

public class MyAutoLogInterceptor extends AbstractAutoLogInterceptor {

    @Override
    protected void doBefore(AutoLog autoLog, IAutoLogInterceptorContext context) {
        System.out.println("Custom input parameters:" + Arrays.toString(context.filterParams()));
    }

    @Override
    protected void doAfter(AutoLog autoLog, Object result, IAutoLogInterceptorContext context) {
        System.out.println("Custom output parameters:" + result);
    }

    @Override
    protected void doException(AutoLog autoLog, Exception exception, IAutoLogInterceptorContext context) {
        System.out.println("Custom exception:");
        exception.printStackTrace();
    }

}

use

As follows, the log output will use the above specified policy.

@AutoLog(interceptor = MyAutoLogInterceptor.class)
public String my() {
    return "Custom policy";
}

Custom parameter filter (paramFilter)

built-in

WebParamFilter is mainly used to filter objects that cannot be directly serialized by JSON, such as httprequest and httpservlet.

custom

Directly inherit the AbstractParamFilter class and implement the corresponding method.

public class MyParamFilter extends AbstractParamFilter {

    @Override
    protected Object[] doFilter(Object[] params) {
        Object[] newParams = new Object[1];
        newParams[0] = "Set the value I want";
        return newParams;
    }

}

use

Specify the corresponding parameter filter. In this way, no matter what the input parameter is, it will become the [set the value I want] specified by us.

@AutoLog(paramFilter = MyParamFilter.class)
public String paramFilter() {
    return "Custom input filter";
}

spring integrated use

Complete example reference SpringServiceTest

Annotation statement

Use @ EnableAutoLog to enable automatic log output

@Configurable
@ComponentScan(basePackages = "com.github.houbb.auto.log.test.service")
@EnableAutoLog
public class SpringConfig {
}

Test code

@ContextConfiguration(classes = SpringConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void queryLogTest() {
        userService.queryLog("1");
    }

}
  • Output results
information: public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) param is [1]
May 30, 2020 12:17:51 afternoon com.github.houbb.auto.log.core.support.interceptor.AutoLogMethodInterceptor info
 information: public java.lang.String com.github.houbb.auto.log.test.service.impl.UserServiceImpl.queryLog(java.lang.String) result is result-1
 May 30, 2020 12:17:51 afternoon org.springframework.context.support.GenericApplicationContext doClose

Integrated use of springboot

maven introduction

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>auto-log-springboot-starter</artifactId>
    <version>Latest version</version>
</dependency>

You only need to import jar s, and you don't need to configure anything else.

Use the same way as spring.

test

@Autowired
private UserService userService;

@Test
public void queryLogTest() {
    userService.query("spring-boot");
}

Open source address

Github: https://github.com/houbb/auto-log

Gitee: https://gitee.com/houbinbin/auto-log

Road-Map

  • [] method path name in optimization log

Consider completing the corresponding class information

  • [] global configuration

For example, the global slow log threshold setting

  • [] JVM sandbox feature
  • [] compile time annotation feature

Original address

java annotation combined with spring aop to automatically output logs and add interceptors and filters

Tags: log4j AOP

Posted by zulfiboy on Sat, 14 May 2022 19:23:16 +0300