In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-11 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
Today, I will talk to you about the internal implementation of Tomcat in Logging, which may not be well understood by many people. In order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.
The Logging implementation of Tomcat outputs content through the Log of JDK and rewriting the Handler of its Log.
The following will analyze the implementation of Log within Tomcat, and go deep into the source code to understand its creation according to the configuration
A series of processes such as Handler.
Initialization
The Main-Class of Tomcat is the class BootStrap, and the initialization of Log also starts with the initialization of this class, because the BootStrap class has the following declaration:
Private static final Log log = LogFactory.getLog (Bootstrap.class)
So this field is also initialized when the class is instantiated.
Start with the factory method of LogFactory
Public Log getInstance (String name) {
If (discoveredLogConstructor = = null) {
Return DirectJDKLog.getInstance (name)
}
Return discoveredLogConstructor.newInstance (name)
By default, Tomcat uses DirectJDKLog, so subsequent processes are handed over to
DirectJDKLog will handle it. Inside the class is a direct logging call to JDK
Public DirectJDKLog (String name) {
Logger=Logger.getLogger (name)
}
In fact, the entire Logger will still be managed by a LogManager. In the last article, we also saw that Tomcat also specified a custom LogManager.
This class is ClassLoaderLogManager.
When Logger acquires LogManager, it involves the process of reading logging.properties. Since ClassLoaderLogManager inherits LogManager, the readConfiguration method is implemented by subclasses. In this case, the custom reading method of Tomcat is as follows:
URL logConfig = ((URLClassLoader) classLoader) .findResource ("logging.properties")
That is, find the resource named logging.properties in the current classLoader. If the logging.properties that comes with JDK does not exist in the current classLoader, after finding the file, it will directly load the properties file, and then parse the properties in the file.
As in the following code, we see parsing handlers as well as custom handler with prefix.
/ / Create handlers for the root logger of this classloader
String rootHandlers = info.props.getProperty (".handlers")
String handlers = info.props.getProperty ("handlers")
Logger localRootLogger = info.rootNode.logger
If (handlers! = null) {
StringTokenizer tok = new StringTokenizer (handlers, ",")
While (tok.hasMoreTokens ()) {
String handlerName = (tok.nextToken () .trim ())
String handlerClassName = handlerName
String prefix = ""
If (handlerClassName.length () = 0) {
Prefix = handlerClassName.substring (0, pos + 1)
HandlerClassName = handlerClassName.substring (pos + 1);}}
Try {
This.prefix.set (prefix)
Handler handler =
(Handler) classLoader.loadClass (handlerClassName). NewInstance (); / / after parsing prefix and handlerClass, many operations are actually performed after newInstance, including setting and initializing specific Handler, opening the output stream, and so on. The operation of setting up the Log file mentioned in the previous article is at this step.
This.prefix.set (null)
Info.handlers.put (handlerName, handler)
If (rootHandlers = = null) {
LocalRootLogger.addHandler (handler);} / / bind handler and logger after parsing.
} catch (Exception e) {}
In loadClass (handlerClassName). NewInstance, there is another key point. When initializing AsynFileHandler, the initialization code in the class contains these two lines.
Protected static final LoggerThread logger = new LoggerThread ()
Static {
Logger.start ()
}
This Logger thread will not stop processing log later, and its run method looks like this:
While (run) {
Try {
LogEntry entry = queue.poll (LOGGER_SLEEP_TIME, TimeUnit.MILLISECONDS); / / log dequeued
If (entryboarding null) entry.flush ()
} catch (InterruptedException x) {
/ / Ignore the attempt to interrupt the thread.
} catch (Exception x) {
X.printStackTrace ()
}
}
Write down a Log
We usually use the form of log.info (xxx) directly when recording log, and this is also the case within Tomcat.
For example, if you want to write down a log.warn with log, the code to be called and executed is this process:
First, it will be called into the DirectJDKLog mentioned above, and the corresponding method will set the Level of Log, and so on. The method looks like this:
Public final void warn (Object message) {
Log (Level.WARNING, String.valueOf (message), null)
}
This line of code, which calls the following code in Logger, will output log according to the configured Handler
For (Handler handler: loggerHandlers) {
Handler.publish (record)
}
The Handler we defined contains FileHandler and ConsoleHandler. At this point, the publish method of FileHandler performs the operation of adding Log to a blocking queue, that is, the queue of the above LogThread in wait
Public void publish (LogRecord record) {
LogEntry entry = new LogEntry (record,this)
Boolean added = false
Try {
While (! added & &! queue.offer (entry)) {.}
LogThread outputs LogEntry when queue is not empty.
We see that the specific operation of this output Log is as follows, using the Formatter mentioned in the previous article.
Public void publish (LogRecord record) {
Timestamp ts = new Timestamp (System.currentTimeMillis ())
String tsString = ts.toString () .substring (0,19)
String tsDate = tsString.substring (0,10)
Try {
/ / If the date has changed, switch log files
If (rotatable & &! date.equals (tsDate)) {
Try {
/ / Make sure another thread hasn't already done this
If (! date.equals (tsDate)) {
CloseWriter ()
Date = tsDate
OpenWriter ()
}}}
String result = null
Result = getFormatter () .format (record); / / format, note
If (writerships written null) {
Writer.write (result); / / use the Writer created during initialization here
If (bufferSize < 0) {
Writer.flush ()
}
After reading the above, do you have any further understanding of Tomcat's internal implementation of Logging? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.
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.