common-logging--源码之SimpleLog

2024-06-17 11:18

本文主要是介绍common-logging--源码之SimpleLog,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • common-logging源码Log接口

在common-logging的源码中,将log核心类抽象成了一个Log接口。

这里贴出Log接口的源码:

/** Licensed to the Apache Software Foundation (ASF) under one or more* contributor license agreements.  See the NOTICE file distributed with* this work for additional information regarding copyright ownership.* The ASF licenses this file to You under the Apache License, Version 2.0* (the "License"); you may not use this file except in compliance with* the License.  You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.apache.commons.logging;/*** A simple logging interface abstracting logging APIs.  In order to be* instantiated successfully by {@link LogFactory}, classes that implement* this interface must have a constructor that takes a single String* parameter representing the "name" of this Log.* <p>* The six logging levels used by <code>Log</code> are (in order):* <ol>* <li>trace (the least serious)</li>* <li>debug</li>* <li>info</li>* <li>warn</li>* <li>error</li>* <li>fatal (the most serious)</li>* </ol>* The mapping of these log levels to the concepts used by the underlying* logging system is implementation dependent.* The implementation should ensure, though, that this ordering behaves* as expected.* <p>* Performance is often a logging concern.* By examining the appropriate property,* a component can avoid expensive operations (producing information* to be logged).* <p>* For example,* <pre>*    if (log.isDebugEnabled()) {*        ... do something expensive ...*        log.debug(theResult);*    }* </pre>* <p>* Configuration of the underlying logging system will generally be done* external to the Logging APIs, through whatever mechanism is supported by* that system.** @version $Id: Log.java 1606045 2014-06-27 12:11:56Z tn $*/
public interface Log {/*** Logs a message with debug log level.** @param message log this message*/void debug(Object message);/*** Logs an error with debug log level.** @param message log this message* @param t log this cause*/void debug(Object message, Throwable t);/*** Logs a message with error log level.** @param message log this message*/void error(Object message);/*** Logs an error with error log level.** @param message log this message* @param t log this cause*/void error(Object message, Throwable t);/*** Logs a message with fatal log level.** @param message log this message*/void fatal(Object message);/*** Logs an error with fatal log level.** @param message log this message* @param t log this cause*/void fatal(Object message, Throwable t);/*** Logs a message with info log level.** @param message log this message*/void info(Object message);/*** Logs an error with info log level.** @param message log this message* @param t log this cause*/void info(Object message, Throwable t);/*** Is debug logging currently enabled?* <p>* Call this method to prevent having to perform expensive operations* (for example, <code>String</code> concatenation)* when the log level is more than debug.** @return true if debug is enabled in the underlying logger.*/boolean isDebugEnabled();/*** Is error logging currently enabled?* <p>* Call this method to prevent having to perform expensive operations* (for example, <code>String</code> concatenation)* when the log level is more than error.** @return true if error is enabled in the underlying logger.*/boolean isErrorEnabled();/*** Is fatal logging currently enabled?* <p>* Call this method to prevent having to perform expensive operations* (for example, <code>String</code> concatenation)* when the log level is more than fatal.** @return true if fatal is enabled in the underlying logger.*/boolean isFatalEnabled();/*** Is info logging currently enabled?* <p>* Call this method to prevent having to perform expensive operations* (for example, <code>String</code> concatenation)* when the log level is more than info.** @return true if info is enabled in the underlying logger.*/boolean isInfoEnabled();/*** Is trace logging currently enabled?* <p>* Call this method to prevent having to perform expensive operations* (for example, <code>String</code> concatenation)* when the log level is more than trace.** @return true if trace is enabled in the underlying logger.*/boolean isTraceEnabled();/*** Is warn logging currently enabled?* <p>* Call this method to prevent having to perform expensive operations* (for example, <code>String</code> concatenation)* when the log level is more than warn.** @return true if warn is enabled in the underlying logger.*/boolean isWarnEnabled();/*** Logs a message with trace log level.** @param message log this message*/void trace(Object message);/*** Logs an error with trace log level.** @param message log this message* @param t log this cause*/void trace(Object message, Throwable t);/*** Logs a message with warn log level.** @param message log this message*/void warn(Object message);/*** Logs an error with warn log level.** @param message log this message* @param t log this cause*/void warn(Object message, Throwable t);
}

  • common-logging源码simpleLog类

前面的博客中,我自己模拟写了一套log4j,这里贴出common-logging中的一个简单例子源码,大致的代码比我前面写的有点差不多,只不过几个值得性能上注意的点还是值得学习的。

/** Licensed to the Apache Software Foundation (ASF) under one or more* contributor license agreements.  See the NOTICE file distributed with* this work for additional information regarding copyright ownership.* The ASF licenses this file to You under the Apache License, Version 2.0* (the "License"); you may not use this file except in compliance with* the License.  You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.apache.commons.logging.impl;import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogConfigurationException;/*** Simple implementation of Log that sends all enabled log messages,* for all defined loggers, to System.err.  The following system properties* are supported to configure the behavior of this logger:* <ul>* <li><code>org.apache.commons.logging.simplelog.defaultlog</code> -*     Default logging detail level for all instances of SimpleLog.*     Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").*     If not specified, defaults to "info". </li>* <li><code>org.apache.commons.logging.simplelog.log.xxxxx</code> -*     Logging detail level for a SimpleLog instance named "xxxxx".*     Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").*     If not specified, the default logging detail level is used.</li>* <li><code>org.apache.commons.logging.simplelog.showlogname</code> -*     Set to <code>true</code> if you want the Log instance name to be*     included in output messages. Defaults to <code>false</code>.</li>* <li><code>org.apache.commons.logging.simplelog.showShortLogname</code> -*     Set to <code>true</code> if you want the last component of the name to be*     included in output messages. Defaults to <code>true</code>.</li>* <li><code>org.apache.commons.logging.simplelog.showdatetime</code> -*     Set to <code>true</code> if you want the current date and time*     to be included in output messages. Default is <code>false</code>.</li>* <li><code>org.apache.commons.logging.simplelog.dateTimeFormat</code> -*     The date and time format to be used in the output messages.*     The pattern describing the date and time format is the same that is*     used in <code>java.text.SimpleDateFormat</code>. If the format is not*     specified or is invalid, the default format is used.*     The default format is <code>yyyy/MM/dd HH:mm:ss:SSS zzz</code>.</li>* </ul>* <p>* In addition to looking for system properties with the names specified* above, this implementation also checks for a class loader resource named* <code>"simplelog.properties"</code>, and includes any matching definitions* from this resource (if it exists).** @version $Id: SimpleLog.java 1435115 2013-01-18 12:40:19Z tn $*/
public class SimpleLog implements Log, Serializable {/** Serializable version identifier. */private static final long serialVersionUID = 136942970684951178L;// ------------------------------------------------------- Class Attributes/** All system properties used by <code>SimpleLog</code> start with this */static protected final String systemPrefix = "org.apache.commons.logging.simplelog.";/** Properties loaded from simplelog.properties */static protected final Properties simpleLogProps = new Properties();/** The default format to use when formating dates */static protected final String DEFAULT_DATE_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss:SSS zzz";/** Include the instance name in the log message? */static volatile protected boolean showLogName = false;/** Include the short name ( last component ) of the logger in the log*  message. Defaults to true - otherwise we'll be lost in a flood of*  messages without knowing who sends them.*/static volatile protected boolean showShortName = true;/** Include the current time in the log message */static volatile protected boolean showDateTime = false;/** The date and time format to use in the log message */static volatile protected String dateTimeFormat = DEFAULT_DATE_TIME_FORMAT;/*** Used to format times.* <p>* Any code that accesses this object should first obtain a lock on it,* ie use synchronized(dateFormatter); this requirement was introduced* in 1.1.1 to fix an existing thread safety bug (SimpleDateFormat.format* is not thread-safe).*/static protected DateFormat dateFormatter = null;// ---------------------------------------------------- Log Level Constants/** "Trace" level logging. */public static final int LOG_LEVEL_TRACE  = 1;/** "Debug" level logging. */public static final int LOG_LEVEL_DEBUG  = 2;/** "Info" level logging. */public static final int LOG_LEVEL_INFO   = 3;/** "Warn" level logging. */public static final int LOG_LEVEL_WARN   = 4;/** "Error" level logging. */public static final int LOG_LEVEL_ERROR  = 5;/** "Fatal" level logging. */public static final int LOG_LEVEL_FATAL  = 6;/** Enable all logging levels */public static final int LOG_LEVEL_ALL    = LOG_LEVEL_TRACE - 1;/** Enable no logging levels */public static final int LOG_LEVEL_OFF    = LOG_LEVEL_FATAL + 1;// ------------------------------------------------------------ Initializerprivate static String getStringProperty(String name) {String prop = null;try {prop = System.getProperty(name);} catch (SecurityException e) {// Ignore}return prop == null ? simpleLogProps.getProperty(name) : prop;}private static String getStringProperty(String name, String dephault) {String prop = getStringProperty(name);return prop == null ? dephault : prop;}private static boolean getBooleanProperty(String name, boolean dephault) {String prop = getStringProperty(name);return prop == null ? dephault : "true".equalsIgnoreCase(prop);}// Initialize class attributes.// Load properties file, if found.// Override with system properties.static {// Add props from the resource simplelog.propertiesInputStream in = getResourceAsStream("simplelog.properties");if(null != in) {try {simpleLogProps.load(in);in.close();} catch(java.io.IOException e) {// ignored}}showLogName = getBooleanProperty(systemPrefix + "showlogname", showLogName);showShortName = getBooleanProperty(systemPrefix + "showShortLogname", showShortName);showDateTime = getBooleanProperty(systemPrefix + "showdatetime", showDateTime);if(showDateTime) {dateTimeFormat = getStringProperty(systemPrefix + "dateTimeFormat",dateTimeFormat);try {dateFormatter = new SimpleDateFormat(dateTimeFormat);} catch(IllegalArgumentException e) {// If the format pattern is invalid - use the default formatdateTimeFormat = DEFAULT_DATE_TIME_FORMAT;dateFormatter = new SimpleDateFormat(dateTimeFormat);}}}// ------------------------------------------------------------- Attributes/** The name of this simple log instance */protected volatile String logName = null;/** The current log level */protected volatile int currentLogLevel;/** The short name of this simple log instance */private volatile String shortLogName = null;// ------------------------------------------------------------ Constructor/*** Construct a simple log with given name.** @param name log name*/public SimpleLog(String name) {logName = name;// Set initial log level// Used to be: set default log level to ERROR// IMHO it should be lower, but at least info ( costin ).setLevel(SimpleLog.LOG_LEVEL_INFO);// Set log level from propertiesString lvl = getStringProperty(systemPrefix + "log." + logName);int i = String.valueOf(name).lastIndexOf(".");while(null == lvl && i > -1) {name = name.substring(0,i);lvl = getStringProperty(systemPrefix + "log." + name);i = String.valueOf(name).lastIndexOf(".");}if(null == lvl) {lvl =  getStringProperty(systemPrefix + "defaultlog");}if("all".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_ALL);} else if("trace".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_TRACE);} else if("debug".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_DEBUG);} else if("info".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_INFO);} else if("warn".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_WARN);} else if("error".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_ERROR);} else if("fatal".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_FATAL);} else if("off".equalsIgnoreCase(lvl)) {setLevel(SimpleLog.LOG_LEVEL_OFF);}}// -------------------------------------------------------- Properties/*** Set logging level.** @param currentLogLevel new logging level*/public void setLevel(int currentLogLevel) {this.currentLogLevel = currentLogLevel;}/*** Get logging level.*/public int getLevel() {return currentLogLevel;}// -------------------------------------------------------- Logging Methods/*** Do the actual logging.* <p>* This method assembles the message and then calls <code>write()</code>* to cause it to be written.** @param type One of the LOG_LEVEL_XXX constants defining the log level* @param message The message itself (typically a String)* @param t The exception whose stack trace should be logged*/protected void log(int type, Object message, Throwable t) {// Use a string buffer for better performancefinal StringBuffer buf = new StringBuffer();// Append date-time if so configuredif(showDateTime) {final Date now = new Date();String dateText;synchronized(dateFormatter) {dateText = dateFormatter.format(now);}buf.append(dateText);buf.append(" ");}// Append a readable representation of the log levelswitch(type) {case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break;case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break;case SimpleLog.LOG_LEVEL_INFO:  buf.append("[INFO] ");  break;case SimpleLog.LOG_LEVEL_WARN:  buf.append("[WARN] ");  break;case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break;case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break;}// Append the name of the log instance if so configuredif(showShortName) {if(shortLogName == null) {// Cut all but the last component of the name for both stylesfinal String slName = logName.substring(logName.lastIndexOf(".") + 1);shortLogName = slName.substring(slName.lastIndexOf("/") + 1);}buf.append(String.valueOf(shortLogName)).append(" - ");} else if(showLogName) {buf.append(String.valueOf(logName)).append(" - ");}// Append the messagebuf.append(String.valueOf(message));// Append stack trace if not nullif(t != null) {buf.append(" <");buf.append(t.toString());buf.append(">");final java.io.StringWriter sw = new java.io.StringWriter(1024);final java.io.PrintWriter pw = new java.io.PrintWriter(sw);t.printStackTrace(pw);pw.close();buf.append(sw.toString());}// Print to the appropriate destinationwrite(buf);}/*** Write the content of the message accumulated in the specified* <code>StringBuffer</code> to the appropriate output destination.  The* default implementation writes to <code>System.err</code>.** @param buffer A <code>StringBuffer</code> containing the accumulated*  text to be logged*/protected void write(StringBuffer buffer) {System.err.println(buffer.toString());}/*** Is the given log level currently enabled?** @param logLevel is this level enabled?*/protected boolean isLevelEnabled(int logLevel) {// log level are numerically ordered so can use simple numeric// comparisonreturn logLevel >= currentLogLevel;}// -------------------------------------------------------- Log Implementation/*** Logs a message with* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG</code>.** @param message to log* @see org.apache.commons.logging.Log#debug(Object)*/public final void debug(Object message) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {log(SimpleLog.LOG_LEVEL_DEBUG, message, null);}}/*** Logs a message with* <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG</code>.** @param message to log* @param t log this cause* @see org.apache.commons.logging.Log#debug(Object, Throwable)*/public final void debug(Object message, Throwable t) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {log(SimpleLog.LOG_LEVEL_DEBUG, message, t);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE</code>.** @param message to log* @see org.apache.commons.logging.Log#trace(Object)*/public final void trace(Object message) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {log(SimpleLog.LOG_LEVEL_TRACE, message, null);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE</code>.** @param message to log* @param t log this cause* @see org.apache.commons.logging.Log#trace(Object, Throwable)*/public final void trace(Object message, Throwable t) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {log(SimpleLog.LOG_LEVEL_TRACE, message, t);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO</code>.** @param message to log* @see org.apache.commons.logging.Log#info(Object)*/public final void info(Object message) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {log(SimpleLog.LOG_LEVEL_INFO,message,null);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO</code>.** @param message to log* @param t log this cause* @see org.apache.commons.logging.Log#info(Object, Throwable)*/public final void info(Object message, Throwable t) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {log(SimpleLog.LOG_LEVEL_INFO, message, t);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN</code>.** @param message to log* @see org.apache.commons.logging.Log#warn(Object)*/public final void warn(Object message) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {log(SimpleLog.LOG_LEVEL_WARN, message, null);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN</code>.** @param message to log* @param t log this cause* @see org.apache.commons.logging.Log#warn(Object, Throwable)*/public final void warn(Object message, Throwable t) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {log(SimpleLog.LOG_LEVEL_WARN, message, t);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR</code>.** @param message to log* @see org.apache.commons.logging.Log#error(Object)*/public final void error(Object message) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {log(SimpleLog.LOG_LEVEL_ERROR, message, null);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR</code>.** @param message to log* @param t log this cause* @see org.apache.commons.logging.Log#error(Object, Throwable)*/public final void error(Object message, Throwable t) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {log(SimpleLog.LOG_LEVEL_ERROR, message, t);}}/*** Log a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL</code>.** @param message to log* @see org.apache.commons.logging.Log#fatal(Object)*/public final void fatal(Object message) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {log(SimpleLog.LOG_LEVEL_FATAL, message, null);}}/*** Logs a message with <code>org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL</code>.** @param message to log* @param t log this cause* @see org.apache.commons.logging.Log#fatal(Object, Throwable)*/public final void fatal(Object message, Throwable t) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {log(SimpleLog.LOG_LEVEL_FATAL, message, t);}}/*** Are debug messages currently enabled?* <p>* This allows expensive operations such as <code>String</code>* concatenation to be avoided when the message will be ignored by the* logger.*/public final boolean isDebugEnabled() {return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);}/*** Are error messages currently enabled?* <p>* This allows expensive operations such as <code>String</code>* concatenation to be avoided when the message will be ignored by the* logger.*/public final boolean isErrorEnabled() {return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);}/*** Are fatal messages currently enabled?* <p>* This allows expensive operations such as <code>String</code>* concatenation to be avoided when the message will be ignored by the* logger.*/public final boolean isFatalEnabled() {return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);}/*** Are info messages currently enabled?* <p>* This allows expensive operations such as <code>String</code>* concatenation to be avoided when the message will be ignored by the* logger.*/public final boolean isInfoEnabled() {return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);}/*** Are trace messages currently enabled?* <p>* This allows expensive operations such as <code>String</code>* concatenation to be avoided when the message will be ignored by the* logger.*/public final boolean isTraceEnabled() {return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);}/*** Are warn messages currently enabled?* <p>* This allows expensive operations such as <code>String</code>* concatenation to be avoided when the message will be ignored by the* logger.*/public final boolean isWarnEnabled() {return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);}/*** Return the thread context class loader if available.* Otherwise return null.** The thread context class loader is available for JDK 1.2* or later, if certain security conditions are met.** @exception LogConfigurationException if a suitable class loader* cannot be identified.*/private static ClassLoader getContextClassLoader() {ClassLoader classLoader = null;try {// Are we running on a JDK 1.2 or later system?final Method method = Thread.class.getMethod("getContextClassLoader", (Class[]) null);// Get the thread context class loader (if there is one)try {classLoader = (ClassLoader)method.invoke(Thread.currentThread(), (Class[]) null);} catch (IllegalAccessException e) {// ignore} catch (InvocationTargetException e) {/*** InvocationTargetException is thrown by 'invoke' when* the method being invoked (getContextClassLoader) throws* an exception.** getContextClassLoader() throws SecurityException when* the context class loader isn't an ancestor of the* calling class's class loader, or if security* permissions are restricted.** In the first case (not related), we want to ignore and* keep going.  We cannot help but also ignore the second* with the logic below, but other calls elsewhere (to* obtain a class loader) will trigger this exception where* we can make a distinction.*/if (e.getTargetException() instanceof SecurityException) {// ignore} else {// Capture 'e.getTargetException()' exception for details// alternate: log 'e.getTargetException()', and pass back 'e'.throw new LogConfigurationException("Unexpected InvocationTargetException", e.getTargetException());}}} catch (NoSuchMethodException e) {// Assume we are running on JDK 1.1// ignore}if (classLoader == null) {classLoader = SimpleLog.class.getClassLoader();}// Return the selected class loaderreturn classLoader;}private static InputStream getResourceAsStream(final String name) {return (InputStream)AccessController.doPrivileged(new PrivilegedAction() {public Object run() {ClassLoader threadCL = getContextClassLoader();if (threadCL != null) {return threadCL.getResourceAsStream(name);} else {return ClassLoader.getSystemResourceAsStream(name);}}});}
}

  • simpleLog类值得借鉴的地方

1,simpleLog也同样定义了几个静态常量用来保存从配置文件中读取出来的日志输出控制字段,在这里用了volatile关键字修饰,避免了线程问题。关于volatile关键字我前面的博客里面有,在写完自己的一套web框架后,我会认真的整理下并发编程,关于这块短板以后会补充起来。

2,simpleLog类中几个输出日志的方法,比如debug(),info()等在调用核心log()方法之前都先加一个逻辑控制。

 public final void debug(Object message) {if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {log(SimpleLog.LOG_LEVEL_DEBUG, message, null);}}

代码相对比较严谨,而且这里加一个开关也控制了不必要的性能消耗,当然这个开关也直接拎出来了,我们在实际的业务代码中写日志输出的时候也可以调用来加上控制,提高性能,比如减少一些输出日志的字符串连接等等。

 protected boolean isLevelEnabled(int logLevel) {// log level are numerically ordered so can use simple numeric// comparisonreturn logLevel >= currentLogLevel;}

3,从properties文件中读取配置的几个方法,特别是读取Boolean类型属性的方法,以后我们就不要老土的用Boolean.booleanValue()了,用一个字符串.equals()就OK。

private static boolean getBooleanProperty(String name, boolean dephault) {String prop = getStringProperty(name);return prop == null ? dephault : "true".equalsIgnoreCase(prop);}

4,加载配置文件获得一个输入流的方法,使用了JDK的几个安全类,这里贴出源码,以后也可以直接拿来使用。

private static ClassLoader getContextClassLoader() {ClassLoader classLoader = null;try {// Are we running on a JDK 1.2 or later system?final Method method = Thread.class.getMethod("getContextClassLoader", (Class[]) null);// Get the thread context class loader (if there is one)try {classLoader = (ClassLoader)method.invoke(Thread.currentThread(), (Class[]) null);} catch (IllegalAccessException e) {// ignore} catch (InvocationTargetException e) {/*** InvocationTargetException is thrown by 'invoke' when* the method being invoked (getContextClassLoader) throws* an exception.** getContextClassLoader() throws SecurityException when* the context class loader isn't an ancestor of the* calling class's class loader, or if security* permissions are restricted.** In the first case (not related), we want to ignore and* keep going.  We cannot help but also ignore the second* with the logic below, but other calls elsewhere (to* obtain a class loader) will trigger this exception where* we can make a distinction.*/if (e.getTargetException() instanceof SecurityException) {// ignore} else {// Capture 'e.getTargetException()' exception for details// alternate: log 'e.getTargetException()', and pass back 'e'.throw new LogConfigurationException("Unexpected InvocationTargetException", e.getTargetException());}}} catch (NoSuchMethodException e) {// Assume we are running on JDK 1.1// ignore}if (classLoader == null) {classLoader = SimpleLog.class.getClassLoader();}// Return the selected class loaderreturn classLoader;}private static InputStream getResourceAsStream(final String name) {return (InputStream)AccessController.doPrivileged(new PrivilegedAction() {public Object run() {ClassLoader threadCL = getContextClassLoader();if (threadCL != null) {return threadCL.getResourceAsStream(name);} else {return ClassLoader.getSystemResourceAsStream(name);}}});}


  • 总结

Commons Logging的设计比较简单,它定义了一个Log接口,所有它支持的日志系统都有相应的Log实现类,如Log4JLogger、Jdk14Logger、Jdk13LumberjackLogger、SimpleLog、NoOpLog、AvalonLogger、LogKitLogger等类,在

LogFactory中定义了一定的规则,从而根据当前的环境和配置取得特定的Log子类实例。关于它是如何去获取特定Log实现的,我下一篇博客会整理到。

这篇关于common-logging--源码之SimpleLog的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1069289

相关文章

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

red5-server源码

red5-server源码:https://github.com/Red5/red5-server

TL-Tomcat中长连接的底层源码原理实现

长连接:浏览器告诉tomcat不要将请求关掉。  如果不是长连接,tomcat响应后会告诉浏览器把这个连接关掉。    tomcat中有一个缓冲区  如果发送大批量数据后 又不处理  那么会堆积缓冲区 后面的请求会越来越慢。

Windows环境利用VS2022编译 libvpx 源码教程

libvpx libvpx 是一个开源的视频编码库,由 WebM 项目开发和维护,专门用于 VP8 和 VP9 视频编码格式的编解码处理。它支持高质量的视频压缩,广泛应用于视频会议、在线教育、视频直播服务等多种场景中。libvpx 的特点包括跨平台兼容性、硬件加速支持以及灵活的接口设计,使其可以轻松集成到各种应用程序中。 libvpx 的安装和配置过程相对简单,用户可以从官方网站下载源代码