标签:之七 logging LogManager util 源码 new java null Tomcat8
Tomcat源码版本:apache-tomcat-8.5.54-src
JDK源码版本:jdk1.8.0_171
1、juli包
(1)Tomcat日志包:org.apache.juli。默认情况下,Tomcat使用自身的juli作为Tomcat内部的日志处理系统,而juli默认使用JDK提供的日志java.util.logging.
java.util.logging的一个特点就是根据classloader进行区分打印日志,不同的web应用使用不同的webappclassloader,因此不同应用的日志就可以区分开来。
(2)三个参数
java.util.logging.manager:LogManager作为全局日志管理器负责维护日志配置和日志继承结构,LogManager通过“java.util.logging.manager”系统参数指定,程序可以通过LogManager.getLogManager()方法得到这个全局日志管理器。
java.util.logging.config.class 为自定义配置类,负责完成配置信息的初始化
java.util.logging.config.file 用于指定自定义配置文件,默认情况下LogManager的配置文件为%JAVA_HOME%/jre/lib/logging.properties,而tomcat一般放在%TOMCAT_HOME%/conf/logging.properties
(3)配置举例
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=E:/workspace/mot/tomcat8.5/conf/logging.properties
然后启动Tomcat,断点看下执行过程:
org.apache.catalina.startup.Bootstrap -->private static final Log log = LogFactory.getLog(Bootstrap.class); -->private static final LogFactory singleton = new LogFactory(); ---->org.apache.juli.logging.LogFactory::getLog ------>org.apache.juli.logging.LogFactory::getInstance -------->org.apache.juli.logging.DirectJDKLog::getInstance ---------->java.util.logging.Logger::getLogger(最终调用JDK中的日志器) ---------->java.util.logging.Logger::demandLogger ------------>java.util.logging.LogManager::getLogManager 得到这个全局日志管理器 ------------>java.util.logging.LogManager::ensureLogManagerInitialized ------------>java.util.logging.LogManager::readPrimordialConfiguration -------------->org.apache.juli.ClassLoaderLogManager::readConfiguration //读取配置
java.util.logging.LogManager源码:
public class LogManager { // The global LogManager object private static final LogManager manager; ...... static { manager = AccessController.doPrivileged(new PrivilegedAction<LogManager>() { @Override public LogManager run() { LogManager mgr = null; String cname = null; try {//静态初始化加载 cname = System.getProperty("java.util.logging.manager"); if (cname != null) { try { Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname); mgr = (LogManager) clz.newInstance(); } catch (ClassNotFoundException ex) { Class<?> clz = Thread.currentThread().getContextClassLoader().loadClass(cname); mgr = (LogManager) clz.newInstance(); } } } catch (Exception ex) { System.err.println("Could not load Logmanager \"" + cname + "\""); ex.printStackTrace(); } if (mgr == null) { mgr = new LogManager(); } return mgr; } }); } ...... public static LogManager getLogManager() { if (manager != null) { manager.ensureLogManagerInitialized(); } return manager; } final void ensureLogManagerInitialized() { final LogManager owner = this; if (initializationDone || owner != manager) { return; } synchronized(this) { ......try { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { assert rootLogger == null; assert initializedCalled && !initializationDone; // Read configuration. owner.readPrimordialConfiguration(); owner.rootLogger = owner.new RootLogger(); owner.addLogger(owner.rootLogger); if (!owner.rootLogger.isLevelInitialized()) { owner.rootLogger.setLevel(defaultLevel); } @SuppressWarnings("deprecation") final Logger global = Logger.global; owner.addLogger(global); return null; } }); } finally { initializationDone = true; } } } private void readPrimordialConfiguration() { if (!readPrimordialConfiguration) { synchronized (this) { if (!readPrimordialConfiguration) { if (System.out == null) { return; } readPrimordialConfiguration = true; try { AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { readConfiguration(); sun.util.logging.PlatformLogger.redirectPlatformLoggers(); return null; } }); } catch (Exception ex) { assert false : "Exception raised while reading logging configuration: " + ex; } } } } } //如果不配置java.util.logging.manager 会读取默认%JAVA_HOME%/jre/lib/logging.properties public void readConfiguration() throws IOException, SecurityException { checkPermission(); // if a configuration class is specified, load it and use it. String cname = System.getProperty("java.util.logging.config.class"); if (cname != null) { try { // Instantiate the named class. It is its constructor's // responsibility to initialize the logging configuration, by // calling readConfiguration(InputStream) with a suitable stream. try { Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname); clz.newInstance(); return; } catch (ClassNotFoundException ex) { Class<?> clz = Thread.currentThread().getContextClassLoader().loadClass(cname); clz.newInstance(); return; } } catch (Exception ex) { System.err.println("Logging configuration class \"" + cname + "\" failed"); System.err.println("" + ex); // keep going and useful config file. } } String fname = System.getProperty("java.util.logging.config.file"); if (fname == null) { fname = System.getProperty("java.home"); if (fname == null) { throw new Error("Can't find java.home ??"); } File f = new File(fname, "lib"); f = new File(f, "logging.properties"); fname = f.getCanonicalPath(); } try (final InputStream in = new FileInputStream(fname)) { final BufferedInputStream bin = new BufferedInputStream(in); readConfiguration(bin); } } ...... }
org.apache.juli.ClassLoaderLogManager.java源码:
public class ClassLoaderLogManager extends LogManager { @Override public void readConfiguration() throws IOException, SecurityException { checkAccess(); readConfiguration(Thread.currentThread().getContextClassLoader()); } protected synchronized void readConfiguration(ClassLoader classLoader) throws IOException { InputStream is = null; try { if (classLoader instanceof WebappProperties) { if (((WebappProperties) classLoader).hasLoggingConfig()) { is = classLoader.getResourceAsStream("logging.properties"); } } else if (classLoader instanceof URLClassLoader) { URL logConfig = ((URLClassLoader)classLoader).findResource("logging.properties"); if(null != logConfig) { if(Boolean.getBoolean(DEBUG_PROPERTY)) System.err.println(getClass().getName() + ".readConfiguration(): " + "Found logging.properties at " + logConfig); is = classLoader.getResourceAsStream("logging.properties"); } else { if(Boolean.getBoolean(DEBUG_PROPERTY)) System.err.println(getClass().getName() + ".readConfiguration(): " + "Found no logging.properties"); } } } catch (AccessControlException ace) { ClassLoaderLogInfo info = classLoaderLoggers.get(ClassLoader.getSystemClassLoader()); if (info != null) { Logger log = info.loggers.get(""); if (log != null) { Permission perm = ace.getPermission(); if (perm instanceof FilePermission && perm.getActions().equals("read")) { log.warning("Reading " + perm.getName() + " is not permitted. See \"per context logging\" in the default catalina.policy file."); } else { log.warning("Reading logging.properties is not permitted in some context. See \"per context logging\" in the default catalina.policy file."); log.warning("Original error was: " + ace.getMessage()); } } } } ...... if (is != null) { readConfiguration(is, classLoader); } try { addingLocalRootLogger.set(Boolean.TRUE); addLogger(localRootLogger); } finally { addingLocalRootLogger.set(Boolean.FALSE); } } protected synchronized void readConfiguration(InputStream is, ClassLoader classLoader) throws IOException { ClassLoaderLogInfo info = classLoaderLoggers.get(classLoader); try { info.props.load(is); } catch (IOException e) { } finally { try { is.close(); } catch (IOException ioe) { } } 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) { continue; } if (Character.isDigit(handlerClassName.charAt(0))) { int pos = handlerClassName.indexOf('.'); if (pos >= 0) { prefix = handlerClassName.substring(0, pos + 1); handlerClassName = handlerClassName.substring(pos + 1); } } try { this.prefix.set(prefix); Handler handler = (Handler) classLoader.loadClass(handlerClassName).getConstructor().newInstance(); this.prefix.set(null); info.handlers.put(handlerName, handler); if (rootHandlers == null) { localRootLogger.addHandler(handler); } } catch (Exception e) { System.err.println("Handler error"); e.printStackTrace(); } } } } @Override public synchronized boolean addLogger(final Logger logger) { final String loggerName = logger.getName(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ClassLoaderLogInfo info = getClassLoaderInfo(classLoader); if (info.loggers.containsKey(loggerName)) { return false; } info.loggers.put(loggerName, logger); // Apply initial level for new logger final String levelString = getProperty(loggerName + ".level"); if (levelString != null) { try { AccessController.doPrivileged(new PrivilegedAction<Void>() { @Override public Void run() { logger.setLevel(Level.parse(levelString.trim())); return null; } }); } catch (IllegalArgumentException e) { // Leave level set to null } } int dotIndex = loggerName.lastIndexOf('.'); if (dotIndex >= 0) { final String parentName = loggerName.substring(0, dotIndex); Logger.getLogger(parentName); } // Find associated node LogNode node = info.rootNode.findNode(loggerName); node.logger = logger; // Set parent logger Logger parentLogger = node.findParentLogger(); if (parentLogger != null) { doSetParentLogger(logger, parentLogger); } // Tell children we are their new parent node.setParentLogger(logger); // Add associated handlers, if any are defined using the .handlers property. // In this case, handlers of the parent logger(s) will not be used String handlers = getProperty(loggerName + ".handlers"); if (handlers != null) { logger.setUseParentHandlers(false); StringTokenizer tok = new StringTokenizer(handlers, ","); while (tok.hasMoreTokens()) { String handlerName = (tok.nextToken().trim()); Handler handler = null; ClassLoader current = classLoader; while (current != null) { info = classLoaderLoggers.get(current); if (info != null) { handler = info.handlers.get(handlerName); if (handler != null) { break; } } current = current.getParent(); } if (handler != null) { logger.addHandler(handler); } } } String useParentHandlersString = getProperty(loggerName + ".useParentHandlers"); if (Boolean.parseBoolean(useParentHandlersString)) { logger.setUseParentHandlers(true); } return true; } ...... }
2、
参考:
Tomcat 8 源码学习五之Tomcat日志系统
Tomcat日志系统详解
java.util.logging.LogManager
标签:之七,logging,LogManager,util,源码,new,java,null,Tomcat8 来源: https://www.cnblogs.com/cac2020/p/12767952.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。