LOG4J - EAR 中不同战争的独立日志文件

LOG4J - Separate log files for different wars in EAR

我有以下场景:一个 EAR,有 3 个 WARs(销售模块、内联网模块和主应用程序 - 一个 lms 系统)。每个 WAR 都有它 log4j.properties 配置单独的日志文件,组织并更容易发现每个系统上的问题。

问题是,这 3 个 war 共享一个依赖项 - 一个核心 jar,与我的服务层(实体、存储库、服务等)。该 jar 没有 log4.properties,此处进行的所有日志记录都转到 server.log。我想避免它。

当我过去单独部署 war 时,一切都很好 - 因为 jar 在 war 中并且与 log4j.properties 一起。所以:

   Request -> Intranet.war -> Core JAR -> all logging here goes to intranet.log
   Request -> LMS.war -> Core JAR -> all logging here goes to lms.log
   Request -> Sales.war -> Core JAR -> all logging here goes to sales.log

现在我在 EAR 的 lib/ 文件夹中只有一个核心 jar,由他们共享。

问题是:如何仍然根据war调用核心来组织日志?

我的意思是,如果我在 EAR 中调用 intranet.war,所有 core.jar 的登录仍然会转到 intranet.log。 LMS 和销售相同。

我正在考虑为整个 EAR 创建一个唯一的 log4j.properties 文件,但我如何在文件中分离?我可以使用包方法(例如 xxx.lms.yyy 转到 lms.log),但是核心 jar 中的包是共享的。

有什么想法吗?

提前致谢!

我找到了一种使其与 CDI 和 ThreadLocal 一起工作的方法。

每个request关联一个thread,所以我做了一个CDI Producer方法,逻辑很简单:当前threadlocal是否有Logger?如果是,return它。如果没有,从 SLF4J LoggerFactory 获取一个,将其保存在 ThreadLocal 中并 return 它。

然后,为了在 wars 和核心 jar 中获取记录器,我这样做:

@Inject @MyQualifier private Logger logger; 
//I created a specific qualifier because one of the frameworks I use also have a Logger Producer

生产者方法:

@Produces @MyQualifier
public Logger getLogger(InjectionPoint ip){

    ThreadLocal<Logger> t = new ThreadLocal<>();
    if(t.get() == null) {
        Class<?> clazz = ip.getMember().getDeclaringClass();
        t.set(org.slf4j.LoggerFactory.getLogger(clazz));
    }
    return t.get();
}

很有魅力!我的 services/daos 类 都是@requestscoped,所以对于每个请求,我只有一个关联的记录器,它在 WAR 中实例化 - log4j.properties 配置为我想要的那个语境。

但是,有一种情况它不起作用:EJB 中的@Schedule 方法。在这种情况下,线程 "created " 不在 war 中,但已经在 jar 上下文中。对于这些情况,我在 EAR 的 META-INF 文件夹中创建了另一个 log4j.properties。现在一切正常。