AopLog is a logging toolkit based on Spring Aop and ThreadLocal to intercept and process request method content logs.
Scenario:
- At present, most of the methods of using Spring Aop to intercept parameter logs are basically the same. I don't want to write such Aop interception and processing log code for every project in the future, or even code intrusion.
- I want to know the request parameters, response parameters, request header, internal time-consuming, success or failure of some relatively important request methods. When an error occurs, I don't know which step of execution has an exception, and whether it is a logic problem caused by a parameter.
- Ordinary log Info or warn information has no up-down relationship with the request, so it is not convenient to view and analyze.
- In the formal environment, I don't want to print too many meaningless info logs (some are just printed for troubleshooting, which is actually meaningless when the program is running normally). I just want to record the log when an exception occurs, or I just want to record only one sub critical request information per request.
- For the collection of logs, I hope to record the logs of these requests. The implementation method of the records is decided by myself, such as normal log printing, common logs written to the database, logs written to files, logs in queues, etc.
- The recording of the whole log does not interfere with the flow of the normal request method. The collection and processing of the log is asynchronous, which does not affect the performance and response of the normal request method.
- You only need to decide whether to record through the @ AopLog annotation.
Quick start
The project passes maven's POM XML import
<dependency> <groupId>com.github.ealenxie</groupId> <artifactId>aop-log</artifactId> <version>2.1</version> </dependency>
Or through gradle
compile group: 'com.github.ealenxie', name: 'aop-log', version: '2.1'
@AopLog annotation is used for logging
Annotate @ AopLog directly on the class (acting on all methods of the class) or class method (acting on methods) for logging
For example:
import com.github.AopLog; import name.ealen.infra.base.resp.RespBody; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author EalenXie create on 2020/6/22 14:28 */ @AopLog(type = "test",stackTraceOnErr = true) @RestController public class AppController { @GetMapping("/app/sayHello") public RespBody<String> sayHello() { return RespBody.ok("hello EalenXie"); } }
Customize the global log collector to implement the LogCollector
For example, simply print, or write to the library, and so on.
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.LogData; import com.github.collector.LogCollector; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /** * @author EalenXie create on 2020/9/15 13:46 * This is a sample reference * Configure a simple log collector. Here is just a log Print info, which can be written to the database or written here */ @Slf4j @Component public class AopLogCollector implements LogCollector { private ObjectMapper objectMapper = new ObjectMapper(); @Override public void collect(LogData logData) { try { log.info(objectMapper.writeValueAsString(logData)); } catch (JsonProcessingException e) { e.printStackTrace(); } } }
Only one global log collector can be configured for @ Component.
The interface calls the / say/hello test to see the results printed on the console:
2020-09-16 16:01:04.782 INFO 2012 --- [AsyncExecutor-2] name.ealen.infra.advice.AopLogCollector : {"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://Localhost: 8080 / APP / sayhello "," httpmethod ":" get "," headers ": {" user agent ":" Apache httpclient / 4.5.10 (Java / 11.0.5) "}," type ":" test "," content ":", "method": "name ealen. api. facade. AppController #sayhello "," args ": null," respbody ": {" code ":" 200 "," desc ":" OK "," message ":" request succeeded "," datetime ":" 2020-09-16 16:01:04 "," body ":" Hello ealenzie "}," logdate ": 1600243264780," costtime ": 1," threadname ":" http-nio-8080-exec-3 "," ThreadID ": 33," success ": true}
Description of the LogData property of the logged log object
Contents of LogData record
|Field | type | comment|
| :------- | :------------ | :----- |
|appName | String | application name|
|host | String | host|
|port | int | port number|
|clientIp | String | Ip of the requesting client|
|Requrl | string | request address|
|Headers | object | request header information (optional record) default record user agent, content type|
|type | String | operation type. The default value is undefined|
|content | String | method step content. It is empty by default. Logdata can be used Step to record the contents and steps|
|Method | string | local java method of the request|
|Args | object | method request parameters|
|respBody | Object | method response parameters|
|costTime | long | the whole method takes time|
|Logdate | date | log generation time, the initialization time of LogData object|
|Threadname | string | thread name|
|ThreadID | long | thread Id|
|Success | Boolean | execution status, success (true) / exception (false)|
Description of AopLog annotation options
option | type | explain | default |
---|---|---|---|
logOnErr | boolean | The collection is recorded only when an exception occurs | false |
type | String | Operation type | The default value is "undefined" |
headers | String[] | Record header information. Select which header information to record | Default "user agent", "content type" |
args | boolean | Record request parameters | true |
respBody | boolean | Record response parameters | true |
stackTraceOnErr | boolean | When an exception occurs in the target method, whether to append the exception stack information to the content of LogData | false |
asyncMode | boolean | Asynchronous collection | true |
collector | Class<? extends LogCollector> | Specify log collector | By default, the collector is not adjusted, and the global log collector is used |
The step method of LogData.
Record the steps. (if some important steps want to be recorded)
For example:
import com.github.AopLog; import com.github.LogData; import name.ealen.infra.base.resp.RespBody; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author EalenXie create on 2020/6/22 14:28 */ @AopLog(type = "test",stackTraceOnErr = true) @RestController public class AppController { @GetMapping("/app/sayHello") public RespBody<String> sayHello() { LogData.step("1. The first step is completed"); //...... LogData.step("2. The second step is completed"); //..... LogData.step("3. service Method execution completed"); //..... return RespBody.ok("hello EalenXie"); } }
Note: if this method is not used in the overall calling link of the method annotated by @ AopLog, the LogData in ThreadLocal in the current thread will not be released, and LogData needs to be called manually removeCurrent();
At this time, call the / say/hello test again to see the results printed on the console. Focus on the content field:
2020-09-16 17:26:20.285 INFO 3284 --- [AsyncExecutor-2] name.ealen.infra.advice.AopLogCollector : {"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://Localhost: 8080 / APP / sayhello "," httpmethod ":" get "," headers ": {" user agent ":" Apache httpclient / 4.5.10 (Java / 11.0.5) "}," type ":" test "," content":"1 The first step is completed \ n2 The second step is completed \ N3 Service method execution completed \ n "," method ":" name ealen. api. facade. AppController #sayhello "," args ": null," respbody ": {" code ":" 200 "," desc ":" OK "," message ":" request success "," dateTime":"2020-09-16 17:26:20","body":"hello EalenXie"},"logDate":1600248380283,"costTime":1,"threadName":"http-nio-8080-exec-2","threadId":32,"success":true}
about
Open source Github address:[ https://github.com/EalenXie/a...
](https://github.com/EalenXie/a...
Thank you for your comments and support.