Tomcat的多webapp要分日志打印的话,简单方案是把日志JAR包各放各webapp的lib目录,分别使用。但是这样的话,日志JAR包加载多份,资源有所浪费。
最好是日志JAR包共用,用其它的隔离机制实现。
万幸,log4j提供了一个叫LoggerRepository的API,可以做这个事情。
实现类图:
本例以使用slf4j打印为例说明。
其中org.apache.log4j.Logger和org.apache.log4j.LoggerRepository为log4j包中类。
org.slf4j.Logger为slf4j-api中类。
Log4jLoggerAdapter用于将log4j的Logger转换为slf4j的Logger,此类在slf4j包中已有,但其访问权限有限,构造函数无修饰符。需要注意。
LogService代码示意:
public class LogService { private org.apache.log4j.Logger logger; private LoggerRepository loggerRepository; /** * Instantiates a new Oss log service. * * @param properties the properties */ public LogService(Properties properties) { initEvn(); new PropertyConfigurator().doConfigure(properties, loggerRepository); } /** * Instantiates a new Oss log service. * * @param logFile the log file */ public LogService(URL logFile) { initEvn(); new PropertyConfigurator().doConfigure(logFile, loggerRepository); } private void initEvn() { logger = new RootLogger(Level.ALL); loggerRepository = new Hierarchy(logger); } /** * Gets logger. * * @param name the name * @return the logger */ public org.apache.log4j.Logger getLogger(String name) { return loggerRepository.getLogger(name); } }
MyLogFactory示例:
public final class MyLogFactory { private static final MyLogFactory FACTORY = new MyLogFactory(); private final Map> instances = new ConcurrentHashMap>(); private final static Map SERVICES = new ConcurrentHashMap(); private static final Map APP_NAMES = new ConcurrentHashMap(); /** * Do configuration. * * @param propertiesFile the properties file */ public static void doConfiguration(File propertiesFile) { if (propertiesFile == null) { return; } String serviceName = getAppName(); LogService logService = SERVICES.get(serviceName); if (logService == null) { try { logService = new LogService(propertiesFile.toURI().toURL()); SERVICES.put(serviceName, logService); } catch (MalformedURLException e) { logService = new LogService(new Properties()); SERVICES.put(serviceName, logService); } } } /** * Do configuration. * * @param properties the properties */ public static void doConfiguration(Properties properties) { if (properties == null) { return; } String serviceName = getAppName(); LogService logService = SERVICES.get(serviceName); if (logService == null) { logService = new LogService(properties); SERVICES.put(serviceName, logService); } } /** * Gets log. * * @param arg0 the arg 0 * @return the log */ public static Logger getLog(Class> arg0) { return FACTORY.getInstance(arg0.getName()); } /** * Gets logger. * * @param arg0 the arg 0 * @return the logger */ public static Logger getLogger(Class> arg0) { return FACTORY.getInstance(arg0.getName()); } /** * Gets log. * * @param name the name * @return the log */ public static Logger getLog(String name) { return FACTORY.getInstance(name); } /** * Gets security log. * * @return the security log */ public static Logger getSecurityLog() { return FACTORY.getInstance("securityLogger"); } /** * Gets instance. * * @param name the name * @return the instance */ public Logger getInstance(String name) { String serviceName = getAppName(); Map logMap = instances.get(serviceName); if (logMap == null) { logMap = new ConcurrentHashMap(); instances.put(serviceName, logMap); Logger log = getLogByName(serviceName, name); logMap.put(name, log); return log; } Logger log = logMap.get(name); if (log == null) { log = getLogByName(serviceName, name); logMap.put(name, log); return log; } return log; } private Logger getLogByName(String serviceName, String name) { LogService logService = SERVICES.get(serviceName); if (null == logService) { try { File appRootDir = new File(getAppRoot(), "etc"); File logProperties = new File(appRootDir, "log4j/log4j-app.properties"); logService = new LogService(logProperties.toURI().toURL()); SERVICES.put(serviceName, logService); } catch (MalformedURLException e) { logService = new LogService(new Properties()); SERVICES.put(serviceName, logService); } } org.apache.log4j.Logger log4jLogger = logService.getLogger(name); return new Log4jLoggerAdapter(log4jLogger); } public static String getLogHome() { ...... } private static String getProcessName() { ...... return ......; } /** * get app name * @return the app name */ public static String getAppName() { String clazzPath = "main"; URL resourceUrl = Thread.currentThread().getContextClassLoader().getResource("/"); if (null != resourceUrl) { clazzPath = resourceUrl.getPath(); } if (!APP_NAMES.containsKey(clazzPath)) { String appName = clazzPath.split("-")[1].split("/")[0]; APP_NAMES.put(clazzPath, appName); } return APP_NAMES.get(clazzPath); } private static String getAppRoot() { return ... ... } }
使用示例:
使用前,调用MyLogFactory.doConfiguration()将log4j.properties配置文件配置到相应webapp的logRepository中。
然后在业务类中使用Logger log = MyLogFactory.getLogger(A.class)获取日志对象,就可以正常使用了。
JAR Tomcat
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。