如何在单个 EAR 中为不同的 war 配置多个 log4j?

发布于 2024-07-17 05:26:57 字数 345 浏览 8 评论 0原文

我有一个 EAR,其结构如下:

APP.ear 
- APP1.war
    - WEB-INF/classes/log4j.properties
- APP2.war
    - WEB-INF/classes/log4j.properties
- app1-ejb.jar
- app2-ejb.jar
- log4j.jar
- spring.jar
- commons-lang.jar (...and other jar)

我希望每个 WAR 都有自己的应用程序日志。 但上面的配置好像不行。 APP1 和 APP2 的日志转到 APP1 的日志。 有没有办法创建单独的应用程序日志?

I have a EAR with structures like:

APP.ear 
- APP1.war
    - WEB-INF/classes/log4j.properties
- APP2.war
    - WEB-INF/classes/log4j.properties
- app1-ejb.jar
- app2-ejb.jar
- log4j.jar
- spring.jar
- commons-lang.jar (...and other jar)

I want each WAR to have their own application log. But it seems the above configuration does not work. Log for APP1 and APP2 goes to APP1's log. Is there anyway to create separate app logs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

归属感 2024-07-24 05:26:57

事实证明,由于类加载器的原因,这是不可能的。 类加载器层次结构如下:

应用程序类加载器 -> Ejb 类加载器 -> war 类加载器

要为单个 war 提供单独的日志,可以将 log4j.jar 放入 war 中,并让 log4j 使用 war 类加载器。 但由于app1-ejb.jar和app2-ebj.jar都需要使用log4j,所以log4j.jar只能放在顶层。 所以 log4j 位于应用程序类加载器级别。

我可以指定一个 log4j 配置来将不同的包记录到不同的文件中。 但是对于像spring这样的通用库来说,日志是无法分离的。

It turns out that it's impossible due to the classloader. The classloader hierarchy is like:

Application classloader -> Ejb classloader -> war classloader

To have a sepearte log for individual war, one can put log4j.jar inside war and let the log4j uses the war classloader. But as both app1-ejb.jar and app2-ebj.jar also need to use log4j, the log4j.jar can only be placed at the top level. So the log4j is on application classloader level.

I can specify a single log4j config to log different package to different files. But for the common library like spring, the log cannot be sepearted.

微暖i 2024-07-24 05:26:57

它不起作用的原因是 log4j 存在于根位置,而是让每个 war 在其 WEB-INF/lib 目录中都有一个 Log4j.jar 并从根目录中删除 log4j.jar。

有关这方面的更多信息,请参阅我的博客文章
http://techcrawler.wordpress.com/

The reason it didnt work because the log4j is present at the root location, instead let each war have a Log4j.jar in its WEB-INF/lib directory and remove the log4j.jar from the root.

For more info on this refer my blog article on this
http://techcrawler.wordpress.com/

慕烟庭风 2024-07-24 05:26:57

您还可以通过使用代码中的 PropertyConfigurator 动态更改属性文件中的 FILE 属性来实现此目的。

You can also do that by dynamically changing the FILE property in the properties file using the PropertyConfigurator in code.

一指流沙 2024-07-24 05:26:57

Logback 是解决这个问题的一个可行的解决方案。 在研究了使用 log4j 实现此功能的不同技巧后,我们决定切换到 Logback。 我在 web 应用程序中使用了 Logback jar 的以下配置。

Web 应用程序内的 Logback 文件包含外部文件:

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration scan="true" scanPeriod="10 seconds">
        <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
            <resetJUL>true</resetJUL>
        </contextListener>

        <contextName>${project.artifactId}</contextName>

        <jmxConfigurator />

        <include file="${logback.configuration.filepath}" />
    </configuration>

${logback.configuration.filepath} 在 Maven 过滤期间被替换为配置文件的 Web 应用程序外部的确切路径(类似于 /opt/server/conf/loback.included.conf)。

然后是 logback.included.conf 的内容(该文件是项目的一部分,通过 build-helper:attach-artifact 交付,因此 $ {project.artifactId} 在 Maven 过滤期间也会被替换):

    <?xml version="1.0" encoding="UTF-8" ?>
    <included>
        <appender name="file" class="ch.qos.logback.core.FileAppender">
            <file>/var/log/server/${project.artifactId}.log</file>
            <encoder>
                <pattern>[@/%contextName] %date{ISO8601} [%-5level] %thread:[%logger] %msg%n</pattern>
            </encoder>
        </appender>

        <root level="INFO">
            <appender-ref ref="file" />
        </root>
    </included>

唯一的限制,被包含文件的内容必须符合包含器的内容。 其实只是写规则而已。

Logback is a viable solution to address this problem. After having look around different hacks to make this work with log4j, we have decided to switch to Logback. I have used the following configuration with Logback jar inside the webapp.

A Logback file inside the webapp which include an external file:

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration scan="true" scanPeriod="10 seconds">
        <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
            <resetJUL>true</resetJUL>
        </contextListener>

        <contextName>${project.artifactId}</contextName>

        <jmxConfigurator />

        <include file="${logback.configuration.filepath}" />
    </configuration>

${logback.configuration.filepath} is replaced during Maven filtering by the exact path, external to the webapp of the configuration file (something like /opt/server/conf/loback.included.conf).

And then, the content of the logback.included.conf (this file is part of the projetct, delivered with build-helper:attach-artifact, so ${project.artifactId} is also replaced during Maven filtering):

    <?xml version="1.0" encoding="UTF-8" ?>
    <included>
        <appender name="file" class="ch.qos.logback.core.FileAppender">
            <file>/var/log/server/${project.artifactId}.log</file>
            <encoder>
                <pattern>[@/%contextName] %date{ISO8601} [%-5level] %thread:[%logger] %msg%n</pattern>
            </encoder>
        </appender>

        <root level="INFO">
            <appender-ref ref="file" />
        </root>
    </included>

Only limitation, the content of the included file must be compliant with the one of the includer. Just writing rules in fact.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文