In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Most people do not understand the knowledge points of this article "what is the Logger architecture of the open source log library?", so the editor summarizes the following contents, detailed contents, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "what is the Logger architecture of the open source log library" article.
Detailed analysis of the overall architecture diagram of the library
From the point of view of use, we draw cocoons and peel off the Logger library:
String userName = "Jerry"; Logger.i (userName)
Take a look at the method Logger.i ():
Public static void i (String message, Object... Args) {printer.i (message, args);}
There is also a variable parameter, let's see what printer.i (message, args) is:
Public Interface Printer {void I (String message, Object...) Args);}
Is an interface, then we need to find the implementation class of this interface and find the place where the printer object is declared in the Logger class:
Private static Printer printer = new LoggerPrinter ()
The implementation class is LoggerPrinter, and this is also a static member variable, which is useful. As we'll talk about later, continue to trace the I (String message, Object...) of the LoggerPrinter class. Args) method is implemented:
@ Override public void i (String message, Object... Args) {log (INFO, null, message, args);} / * * This method is synchronized in order to avoid messy of logs' order.*/private synchronized void log (int priority, Throwable throwable, String msg, Object...) Args) {/ / determine the currently set log level. If NONE is used, the log if (settings.getLogLevel () = = LogLevel.NONE) {return;} / / get tagString tag = getTag (); / / create the printed message String message = createMessage (msg, args); / / print log (priority, tag, message, throwable);} public enum LogLevel {/ * * Prints all logs*/FULL,/*** No log will be printed*/NONE}
First of all, the log method is a thread-safe synchronization method, which is necessary in a multithreaded environment in order to prevent the log from being printed out of order. Second, determine the print level of the log configuration, FULL prints all logs, NONE does not print logs. Again, getTag ():
Private final ThreadLocal localTag = new ThreadLocal (); / * * @ return the appropriate tag based on local or global * / private String getTag () {/ / get a local cache tagString tag = localTag.get () from ThreadLocal localTag; if (tag! = null) {localTag.remove (); return tag;} return this.tag;}
This method gets the local or global tag value, returns it when there is a tag in the localTag, and clears the value of the localTag
Next, the createMessage method:
Private String createMessage (String message, Object... Args) {return args = = null | | args.length = = 0? Message: String.format (message, args);}
It is clear here why we do not write args, that is, null, when we use Logger.i (message, args). It can also be printed, and it is the reason why message messages are printed directly. Similarly, the blogger also mentioned in his last article:
Logger.i ("blogger is only% d this year, English name is% s", 16, "Jerry")
Printing logs like this, which can be spliced together with different formats of data, was originally realized by using the String.format method. This presumably small partners used a lot of dynamic character placeholders in String.xml when developing Android applications, so it should be easy to understand the use of this format method.
The main thing is that we have processed the tag, print level, and print messages, and then it's time to print them out:
@ Override public synchronized void log (int priority, String tag, String message, Throwable throwable) {/ / also judge the print switch configured by the library. If NONE does not print the log if (settings.getLogLevel () = = LogLevel.NONE) {return;} / / exception and the message is not empty, get the reason for the exception and convert it into a string and then put it into the printed message if (throwable! = null & & message! = null) {message + = ":" + Helper.getStackTraceString (throwable) } if (throwable! = null & & message = = null) {message = Helper.getStackTraceString (throwable);} if (message = = null) {message = "No message/exception is set";} / / number of acquisition methods int methodCount = getMethodCount (); / / determine whether the message is empty if (Helper.isEmpty (message)) {message = "Empty/NULL log message";} / / print the upper boundary logTopBorder (priority, tag) of the log body / / print the high-quality content of the log body logHeaderContent (priority, tag, methodCount); / / get bytes of message with system's default charset (which is UTF-8 for Android) byte [] bytes = message.getBytes (); int length = bytes.length;// message byte length less than or equal to 4000if (length 0) {/ / the number of methods greater than 0, print the split line logDivider (priority, tag);} / print the message content logContent (priority, tag, message) / print log bottom boundary logBottomBorder (priority, tag); return;} if (methodCount > 0) {logDivider (priority, tag);} for (int I = 0; is default charset (which is UTF-8 for Android) logContent (priority, tag, new String (bytes, I, count));} logBottomBorder (priority, tag);}
Let's focus on the logHeaderContent and logContent methods:
@ SuppressWarnings ("StringBufferReplaceableByString") private void logHeaderContent (int logType, String tag, int methodCount) {/ / get the current thread stack trace element array / / (it stores some information about the method called by the virtual machine: method name, class name, number of lines in the file to call this method) / / this is also the "core" of the library StackTraceElement [] trace = Thread.currentThread (). GetStackTrace () / / determine whether the configuration of the library displays thread information if (settings.isShowThreadInfo ()) {/ / get the name of the current thread, print it, and then print the split line logChunk (logType, tag, HORIZONTAL_DOUBLE_LINE + "Thread:" + Thread.currentThread (). GetName ()); logDivider (logType, tag);} String level = ""; / / get the method start position of the trace stack int stackOffset = getStackOffset (trace) + settings.getMethodOffset () / / corresponding method count with the current stack may exceeds the stack trace. The number of methods tracked by Trims the count// print exceeds the number of methods that can be tracked by the current thread. The total number of tracking methods deducts the offset (the number of methods deducted from the call log), that is, the number of methods that need to be printed: if (methodCount + stackOffset > trace.length) {methodCount = trace.length-stackOffset-1;} for (int I = methodCount; I > 0; iRue -) {int stackIndex = I + stackOffset;if (stackIndex > = trace.length) {continue } / / the path tracking string StringBuilder builder = new StringBuilder () is called by the stitching method stack Builder.append ("U") .append (level) .append (getSimpleClassName (trace [stackIndex]. GetClassName ()) / traced class name.append (".") .append (trace[ stackIndex] .getMethodName ()) / / traced method name.append ("). Append (" ("). Append (trace[ stackIndex] .getFileName ()) / / File name of the method. Append (": ") .append (trace.stackIndex) ] .getLineNumber () / / Line number .append (")" in the file Level + = ""; / / print out the header information logChunk (logType, tag, builder.toString ());}}
Next, take a look at the logContent method:
Private void logContent (int logType, String tag, String chunk) {/ / this function is to get the newline character array. The getProperty method gets the meaning "/ / n" String [] lines = chunk.split ("line.separator"); for (String line: lines) {/ / print out the content logChunk (logType, tag, HORIZONTAL_DOUBLE_LINE + "" + line);}}
As shown in the figure above, the content is an array of strings, and there is no newline character in it, so there is no need for a line break. The printed effect is one line, but there are newline characters in formats like json and xml, so the effect of printing is as follows:
I've been talking about it for most of the day, but I haven't seen the exact print yet. Now let's take a look at the logChunk method:
Private void logChunk (int logType, String tag, String chunk) {/ / finally format tagString finalTag = formatTag (tag); / / print according to different log types, and then give it to LogAdapter to print switch (logType) {case ERROR:settings.getLogAdapter (). E (finalTag, chunk); break;case INFO:settings.getLogAdapter (). I (finalTag, chunk); break;case VERBOSE:settings.getLogAdapter (). V (finalTag, chunk); break Case WARN:settings.getLogAdapter () .w (finalTag, chunk); break;case ASSERT:settings.getLogAdapter () .wtf (finalTag, chunk); break;case DEBUG:// Fall through, log debug by defaultdefault:settings.getLogAdapter () .d (finalTag, chunk); break;}}
This method is very simple, that is, finally format tag, and then leave the printing work to the LogAdapter interface according to different log types. Let's take a look at the method settings.getLogAdapter () (Settings.java file):
Public LogAdapter getLogAdapter () {if (logAdapter = = null) {/ / the final implementation class is AndroidLogAdapterlogAdapter = new AndroidLogAdapter ();} return logAdapter;}
Find the AndroidLogAdapter class:
It turned out to be a big circle, but finally the print was still used: the Log of the system.
All right, the source code of the Logger log framework has been parsed, is there any clearer? maybe my partner will say that this final log print, I don't want to use the system's Log, is it possible to change it? This is natural, look at the overall architecture diagram at the beginning, this LogAdapter is an interface, as long as you implement this interface, do the way you want to print, and then set it through the logAdapter (LogAdapter logAdapter) method of Settings.
The above is the content of this article on "what is the Logger architecture of open source log library". I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.