private LogFactory() {
// Look via a ServiceLoader for a Log implementation that has a
// constructor taking the String name.
ServiceLoader<Log> logLoader = ServiceLoader.load(Log.class);
Constructor<? extends Log> m=null;
for (Log log: logLoader) {
Class<? extends Log> c=log.getClass();
try {
m=c.getConstructor(String.class);
break;
}
catch (NoSuchMethodException | SecurityException e) {
throw new Error(e);
}
}
discoveredLogConstructor=m;
}
public Log getInstance(String name) throws LogConfigurationException {
if (discoveredLogConstructor == null) {
return DirectJDKLog.getInstance(name);
}
try {
return discoveredLogConstructor.newInstance(name);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException |
InvocationTargetException e) {
throw new LogConfigurationException(e);
}
}
tomcat的日志工厂大家发现了么 用ServiceLoader加载的有么有 好吧我们自己写个类来代替默认类吧 当然换成第三方jar也是可以的。
1.首先建立我们自己的log类 要实现org.apache.juli.logging.Log接口哦
另外必须有一个无参构造方法,用于被ServiceLoader进行实例化
2.修改tomcat
在apache-tomcat-9.0.0.M17\bin下找到tomcat-juli.jar
在META-INF文件夹下建立services/org.apache.juli.logging.Log(接口名)这样一个文件,然后在该文件中配置该接口的实现类,如果该接口有多个实现类,一行写一个(以换行符分割),例如:
MyLogImpl
好啦启动tomcat看看结果:
04-Mar-2017 00:46:23.441 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library 1.2.10 using APR version 1.5.2.
04-Mar-2017 00:46:23.442 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
04-Mar-2017 00:46:23.443 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
04-Mar-2017 00:46:24.038 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized (OpenSSL 1.0.2j 26 Sep 2016)
04-Mar-2017 00:46:24.115 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.118 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.121 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.126 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.132 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.149 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.150 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.156 严重 [main] sun.reflect.GeneratedConstructorAccessor1.newInstance -----------my log print-----------
04-Mar-2017 00:46:24.158 信息 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
04-Mar-2017 00:46:24.217 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
自定义日志类
package org.apache.juli.logging;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MyLogImpl implements Log {
private static Logger logger = null;
public MyLogImpl() {
//必须要有的 必须有一个无参构造方法,用于被ServiceLoader进行实例化
}
public MyLogImpl(String name) {
System.out.println("MyLogImpl Constructor Start");
logger = Logger.getLogger(name);
this.log(Level.SEVERE, "-----------my log print-----------", null);
System.out.println("MyLogImpl Constructor End");
}
@Override
public final boolean isErrorEnabled() {
return logger.isLoggable(Level.SEVERE);
}
@Override
public final boolean isWarnEnabled() {
return logger.isLoggable(Level.WARNING);
}
@Override
public final boolean isInfoEnabled() {
return logger.isLoggable(Level.INFO);
}
@Override
public final boolean isDebugEnabled() {
return logger.isLoggable(Level.FINE);
}
@Override
public final boolean isFatalEnabled() {
return logger.isLoggable(Level.SEVERE);
}
@Override
public final boolean isTraceEnabled() {
return logger.isLoggable(Level.FINER);
}
@Override
public final void debug(Object message) {
log(Level.FINE, String.valueOf(message), null);
}
@Override
public final void debug(Object message, Throwable t) {
log(Level.FINE, String.valueOf(message), t);
}
@Override
public final void trace(Object message) {
log(Level.FINER, String.valueOf(message), null);
}
@Override
public final void trace(Object message, Throwable t) {
log(Level.FINER, String.valueOf(message), t);
}
@Override
public final void info(Object message) {
log(Level.INFO, String.valueOf(message), null);
}
@Override
public final void info(Object message, Throwable t) {
log(Level.INFO, String.valueOf(message), t);
}
@Override
public final void warn(Object message) {
log(Level.WARNING, String.valueOf(message), null);
}
@Override
public final void warn(Object message, Throwable t) {
log(Level.WARNING, String.valueOf(message), t);
}
@Override
public final void error(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
@Override
public final void error(Object message, Throwable t) {
log(Level.SEVERE, String.valueOf(message), t);
}
@Override
public final void fatal(Object message) {
log(Level.SEVERE, String.valueOf(message), null);
}
@Override
public final void fatal(Object message, Throwable t) {
log(Level.SEVERE, String.valueOf(message), t);
}
// from commons logging. This would be my number one reason why
// java.util.logging
// is bad - design by committee can be really bad ! The impact on
// performance of
// using java.util.logging - and the ugliness if you need to wrap it - is
// far
// worse than the unfriendly and uncommon default format for logs.
private void log(Level level, String msg, Throwable ex) {
if (logger.isLoggable(level)) {
// Hack (?) to get the stack trace.
Throwable dummyException = new Throwable();
StackTraceElement locations[] = dummyException.getStackTrace();
// Caller will be the third element
String cname = "unknown";
String method = "unknown";
if (locations != null && locations.length > 2) {
StackTraceElement caller = locations[2];
cname = caller.getClassName();
method = caller.getMethodName();
}
if (ex == null) {
logger.logp(level, cname, method, msg);
} else {
logger.logp(level, cname, method, msg, ex);
}
}
}
static Log getInstance(String name) {
return new MyLogImpl(name);
}
}