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)