Tomcat在日志JAR包共享情况下按webapp打印日志方案
【摘要】 Tomcat的多webapp要分日志打印的话,简单方案是把日志JAR包各放各webapp的lib目录,分别使用。但是这样的话,日志JAR包加载多份,资源有所浪费。最好是日志JAR包共用,用其它的隔离机制实现。万幸,log4j提供了一个叫LoggerRepository的API,可以做这个事情。实现类图:本例以使用slf4j打印为例说明。其中org.apache.log4j.Logger和or...
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<String, Map<String, Logger>> instances = new ConcurrentHashMap<String, Map<String, Logger>>(); private final static Map<String, LogService> SERVICES = new ConcurrentHashMap<String, LogService>(); private static final Map<String, String> APP_NAMES = new ConcurrentHashMap<String, String>(); /** * 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<String, Logger> logMap = instances.get(serviceName); if (logMap == null) { logMap = new ConcurrentHashMap<String, Logger>(); 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)获取日志对象,就可以正常使用了。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)