This is the 24th day of my participation in the August Text Challenge.More challenges in August

One, foreword

In the actual development operation and maintenance process, we will encounter the following pain points for logs. We’ll get a taste of it, and suddenly there’s something wrong with the line. And the first thing you want to think about is can the test environment be replicated? If it doesn’t, people will ask a question that hits a sore spot. “Can I see the debug log online? “. And then everyone thinks, I wish I had debug logs online. Then imagination is not good, the reality is skinny. I don’t need to beep here.

Although the reality is painful, it is a pain point for us. This problem has been bothering me for a long time. A long time ago, I wrote an article called “How to implement Log4j to change logging levels online (clustering)” that gave you a basic idea of how to solve these pain points.

But ideas are just ideas, and as Linux guru Linus Torvalds said, “Talk is cheap. Show me the code.” So I finally implemented the above ideas, and officially run online. Now, it ‘s show time!

Second, implementation architecture

In fact, the implementation architecture is very simple, directly to a picture. The core is to connect the configuration center, configuration center everyone according to their own company’s actual use is OK. The configuration (logs for which levels need to be enabled) is sent to the cooperation center through the management terminal, and the configuration center pushes the configuration to the dynamic log framework in the application cluster.

The dynamic logging framework consists of two parts: configuring listeners and logging level modifiers. Configuration listener: Acts as an observer to dynamically listen for configuration rule changes. Log level modifier dynamically modifies logs based on the configuration.

About configuration:

As for the configuration center configuration, it depends on how complex you need to design the dynamic logging framework. The current configuration is a list of lognames. Indicates the lognames for which debug logs need to be enabled.

If we want to get a little more complicated, you can even specify what logs can be turned on for those logNames and for how long. You can even restrict which IP addresses or IP segments can enable these logs and so on.

Anyway, once the basic framework is implemented, you can do whatever you want.

Three, realize the source code

You should also be able to see that the core code of the dynamic logging framework class is the log level modifier. Because configuration listening depends on which configuration center you’re using. So I won’t talk too much about it here. Let’s focus on the log level modifier.

After getting the configuration, dynamically change the log level of the corresponding LogName based on different logging frameworks (such as Log4j, Logback, JDK Logger, etc.). So we have two things in general: 1) support for all logging frameworks; 2. Call the underlying code of the corresponding logging framework to dynamically change the log level.

1. Support all logging frameworks

How can we support all logging frameworks? The key is how to determine that the logging system is being used. Many of you would think that the easiest way to do this would be to simply loop through all of the logging framework’s pronoun code changes every time you make a change. Does this approach really work? Of course not, because if a logging framework is not being used, then usually its corresponding JAR package does not exist, and a direct call will report an error that the class could not find. So you might say, well, I can ask our logging framework to import the required JARS so that we don’t get any errors when we allow them. This doesn’t work either, since most current frameworks, such as Spring Boot, determine which logging framework to use by checking what JARS the application has introduced. So if you introduce all the logging frameworks for your application, you may cause user logging chaos. It’s also not a good implementation. There is another way to do this: try catch. That’s one way to do it, but it’s not perfect.

The perfect and universal solution to this scenario is shown below. That is, in the static block, Class. ForName is used to determine whether the required Class exists, and if so, the current Modifier is registered with the log change engine. In this way, the Modifier registered in the log engine must be Jar, execution will not report an error.

The log engine calls the Load method of each Modifier during initialization to Load the Modifier available for registration.

When the log changes, we simply iterate through all the modifiers in the execution log engine.

2. Dynamically change the log level

From the above code, we already know how to call the Modifier method of the corresponding logging framework when the log is modified. Let’s look at how each logging framework dynamically changes the logging level.

JDK Logger

This one is relatively simple, just paste the code.

Log4j

Logback 

Logging Log4j

You have to pay special attention to this. If LogName is not configured in the log4j configuration file, config.getLoggerConfig cannot be used to obtain the LoggerConfig corresponding to the LogName. Root LoggerConfig is returned. Therefore, the log level of root will be changed.

If root is obtained, create LoggerConfig for the LogName.

At present, only the above log framework is realized, if there are other frameworks we can achieve the corresponding Modifier in accordance with this model.

Four, practice

If you have any questions or comments about this article, please add lifeofCoder.