Wechat public number: Orange Pine Java technology nest article first gold platform, the subsequent synchronous update of the public number, after attention to reply to “plus group” can join the Internet technology exchange & push group, and a group of big factory leaders to discuss interview questions. Reply to “666” to get all the information packages available on the First line Internet (including development software, development specifications, classic e-PDF, and some quality learning courses).
preface
We must have encountered in the development of such a few cases, the interface log is difficult to check ah, server log too much to see dazzling. Fortunately, I can get familiar with these Java troubleshooting tools as mentioned above, and some tools are enough. The key is the server log accumulation alarm, especially the QUALITY assurance environment. After receiving this SMS alarm, you immediately log in to the machine and start an RM operation to solve the problem. You get another SMS alert, familiar, this one again…
Out of curiosity, you open the dock IDEA, look at the screen full of code, and occasionally slightly right click to see the Git master submitter. You want to smash your computer when you know the truth.
Debug logs are not deleted. There is a Warn log with the word ‘xxxTest’. There is a Warn log with the word ‘xxxTest’. Suddenly see a file with a class ending in xxxAspect? Oh? Is this the business side? Just out of curiosity, take a look at the log section, the entry point is all the BIZ business code methods…
So, for the log is not standard, too many server logs, log governance we have a solution, so suddenly, everything and configurable, whether this thing can be configured, so you started to design up,
So many classes, so many methods, I am not each interface log print how can make switch control good? Done!
Switch control is done, so what about the content of the print log? What content should I print? The refs? The return value?
The logs contain the input parameters of the interface, response results, and response time.. Extensible parameters and so on. Done!
The log print content is set, what about the log print level? Every method and every situation may be different. I don’t think it’s the same in different circumstances. What should I do?
Understand, not everything is configured, I make the configuration is not good, configure several different strategies, done!
* the configuration? What do I use for configuration? My project is a distributed project, so after a search in Balabala you may see options like Diamond, Apollo, Disconf, etc., so you roll the dice and choose Apollo
In fact, can hahaha, understand understanding
Dynamic log printing through the control interface blacklist and whitelist log printing, done!
Ok, we have the idea, so let’s start coding
Apollo dynamic configuration enables interface log printing
First, we define an enumeration LogSwitch that controls the switching policy
Description: Need source file plus QQ group [572411121] free request */
public enum LogSwitch {
/** * completely closed */
OFF(1."off"),
/** * open */
PART_ON(2."part on"),
/** * partially closed */
PART_OFF(3."part off"),
/** * fully open */
ON(4."on");
LogSwitch(int code ,String name){
this.code = code;
this.name = name;
}
public static LogSwitch of(int code) {
for(LogSwitch logSwitch : LogSwitch.values()) {
if(logSwitch.getCode() == code) {
returnlogSwitch; }}return null;
}
@Getter
@Setter
private int code;
@Getter
@Setter
private String name;
}
Copy the code
Second, we also define an enumeration LogDimension for the log print content
Description: Need source file plus QQ group [572411121] free request */
public enum LogDimension {
NONE(1."none"),
TIME_ELAPSE(2."time elapse"),
PARAM(3."param"),
RESULT(4."result"),
ALL(5."all");
LogDimension(int code,String name) {
this.code = code;
this.name = name;
}
public static LogDimension of(int code) {
for(LogDimension logDimension : values()) {
if(logDimension.getCode() == code) {
returnlogDimension; }}return null;
}
@Getter
@Setter
private int code;
@Getter
@Setter
private String name;
}
Copy the code
Ok, now that the key elements of the next print log have been formed, we need to define a section class to do it.
Now that we have an aspect, we can use a pointcut annotation to do our aspect, define the log print annotation LogAnnotation doesn’t need any properties, it’s just a facet identifier for us.
/** * @Creator: Gold digging account "Tangerine Pine Java" * @ Created at 2021/7/9 * @ Description: Need to source file to add QQ group [572411121] for free * / @ Retention (RetentionPolicy. RUNTIME) @ Target ({ElementType METHOD, ElementType. TYPE}) @Documented public @interface LogAnnotation { }Copy the code
So now we can write our section class, so we define LogAspect.
Description: Need source file plus QQ group [572411121] free request */
@Component
@Aspect
public class LogAspect {
/** * Log switch level * 1.OFF 2.PART_ON 3.PART_OFF 4.ON *@see LogSwitch
*/
@Value("${log_aspect_switch_level:1}")
private int logSwitch;
NONE 2.TIME_ELAPSE 3.PARAM 4.RESULT *@see LogDimension
*/
@Value("${log_aspect_dimension_level:1}")
private int logDimension;
/** * Method to be processed when logSwitch is 2 signature comma separated * eg. "com.orange.application.xxxClient#getXXX,com.orange.application.xxxClient#getYYY" */
@Value("{log_aspect_part_on_method}")
private String partOnMethods;
/** * Method to exclude when logSwitch is 3 Signature comma separated * eg. "com.orange.application.xxxClient#getXXX,com.orange.application.xxxClient#getYYY" */
@Value("${log_aspect_part_off_method}")
private String partOffMethods;
@Around("@annotation(logAnnotation)")
// Take around notification
public Object processLog (ProceedingJoinPoint joinPoint,LogAnnotation logAnnotation) throws Exception {
// Get the method signature service
String serviceName = joinPoint.getSignature().getDeclaringTypeName();
// Get the method signature method name
String methodName = joinPoint.getSignature().getName();
String methodSignature = serviceName + "#" + methodName;
// Check whether the switch is hit
Boolean isHit = judgeIsHit(methodSignature);
Object obj = null;
// Define log output
List<String> logArray = Lists.newArrayList();
try {
if(! isHit) {// If there is no need to print, execute the logic
obj = joinPoint.proceed();
}else{
// Output the log details according to the enumeration level.
logArray.add(formatParam(joinPoint.getArgs()));
Stopwatch stopwatch =Stopwatch.createStarted();
obj = joinPoint.proceed();
stopwatch.stop();
// Log statistics Time added to logArray Details Log formatting omitted...
logArray.add(formatTimeElapse(stopwatch.toString()));
// Statistics response return value added to logArray details Specific log formatting omitted...logArray.add(formatResult(obj.toString())); }}catch (Exception e) {
// Handle service exceptions
dealBizException(e,joinPoint);
} catch (Throwable throwable) {
dealException(joinPoint);
} finally {
if(isHit){
// If a match is found, a log is printedlog.info(formatLog(methodSignature,logArray)); }}return obj;
}
/** * Check whether the signature matches */
private Boolean judgeIsHit(String methodSignature) {
if(LogSwitch.of(logSwitch) == null || LogDimension.of(logDimension) == null) {
// sign log.... No configuration
return false;
}
if(LogSwitch.ON.getCode() == logSwitch){
// Open all configurations
return true;
}
if(LogSwitch.PART_ON.getCode() == logSwitch) {
// The configuration part is open, matching partOnMethods
return! StringUtils.isEmpty(partOnMethods) && partOnMethods.contains(methodSignature); }if(LogSwitch.PART_OFF.getCode() == logSwitch) {
// The configuration part is open, matching partOffMethods
return! StringUtils.isEmpty(partOffMethods) && ! partOffMethods.contains(methodSignature); }return false;
}
Copy the code
To summarize
Dynamic log printing The unified log output by the corresponding Aspect mainly solves the problem that the log output logic is fixed and the log output is excessive. When troubleshooting, the log content cannot be dynamically adjusted. A unified aspect tool that combines Apollo with annotations to dynamically adjust concerns and control log output. It’s also very easy to use, and you need to annotate @LogAnnotation with LogAspect’s method of dynamically managing logs in your code.
With all the above done, you don’t have to worry about checking the interface log anymore. You can configure it as you want.
Those of you who are interested in more about encapsulation, common components, and common code should check out the common Component encapsulation column on the home page.
Original is not easy, like the students of the blogger a little praise, attention attention, well, see you next time.
The last
- The article is original, original is not easy, thanks for digging gold platform, feel harvest, help three lianha, thank you
- Wechat search public number: Orange pine Java technology nest, make a friend, into the Internet technology exchange group
- All code, sequence diagrams and architecture diagrams involved in the article are shared and can be requested free of charge through the public account plus group
- If the article has the error, welcome the comment message points out, also welcome to reprint, trouble to mark the source is good