log4j 重新部署后不记录

问题描述 投票:0回答:2

我们在

log4j2.xml
基本目录下有
catalina
的通用配置。所以
webapps
下的所有模块都使用这个配置。还有tomcat共享库下的
log4j-core
log4j-web
log4j-api
库。当我们重新启动 tomcat 时,所有模块都会写入日志。但是,当重新部署其中任何一个时,该模块不会记录其他模块。例如,我们在 webapps 文件夹下有
A
B
C
模块。如果我们在重新启动后重新部署
C
模块,那么我们只会看到
C
模块日志。我该如何解决这个问题?我找不到任何原因为什么会发生这种情况

我启用了

log4j
日志来查看发生了什么。重新部署后
log4j
打印这种日志

2021-04-13 17:40:56,930 Catalina-utility-1 DEBUG Registering MBean org.apache.logging.log4j2:type=457e2f02
2021-04-13 17:40:56,930 Catalina-utility-1 DEBUG Registering MBean org.apache.logging.log4j2:type=457e2f02,component=StatusLogger
2021-04-13 17:40:56,930 Catalina-utility-1 DEBUG Registering MBean org.apache.logging.log4j2:type=457e2f02,component=ContextSelector
2021-04-13 17:40:56,930 Catalina-utility-1 DEBUG Registering MBean org.apache.logging.log4j2:type=457e2f02,component=Loggers,name=

457e2f02
这应该是我们的模块名称,但为什么
log4j
打印随机文本

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG" monitoring="10">
    <Properties>
        <Property name="log.level">ALL</Property>
        <Property name="framework.log.level">WARN</Property>
        <Property name="file.pattern">%d{DEFAULT}: [%level{WARN=WAR, DEBUG=DBG, ERROR=ERR, TRACE=TRC, INFO=INF, FATAL=FTL}] %-c.%M[%L] - %m%n</Property>
        <Property name="console.pattern">%highlight{%d{DEFAULT}: [%level{WARN=WAR, DEBUG=DBG, ERROR=ERR, TRACE=TRC, INFO=INF, FATAL=FTL}] %-c.%M[%L] - %m%n \n}{FATAL=red blink, ERROR=red bold, WARN=yellow bold, INFO=green bold, DEBUG=white bold, TRACE=cyan}</Property>
        <Property name="logs.dir">logs</Property>
        <Property name="app.name">magus</Property>
        <Property name="script.test.mode">false</Property>
    </Properties>

    <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
            <PatternLayout pattern="${console.pattern}"/>
        </Console>
    <Socket name="GELF" protocol="tcp" host="graylog.host" port="12201">
            <!-- gelf tcp does not support compression-->
            <GelfLayout includeStackTrace="true" host="${hostName}" includeThreadContext="true" includeNullDelimiter="true"
                  compressionType="OFF">

                <KeyValuePair key="host" value="${hostName}"/>
                <KeyValuePair key="version" value="1.1"/>
                <!--<KeyValuePair key="short_message" value="$${event:Message}"/>--><!--   not required             -->
                <!--<KeyValuePair key="application_name" value="$${ctx:application}"/>-->
                <KeyValuePair key="thread_id" value="$${event:ThreadId}"/>
                <KeyValuePair key="thread_name" value="$${event:ThreadName}"/>
                <KeyValuePair key="timestamp" value="$${event:Timestamp}"/>
                <!--<KeyValuePair key="level" value="1"/>--><!-- default level type is number so we don't use-->
                <KeyValuePair key="log_level" value="$${event:Level}"/><!-- for readabilty and filtering-->
            </GelfLayout>
        </Socket>
        <RollingFile name="LOG" fileName="${logs.dir}/${app.name}.log"
                     filePattern="${logs.dir}/$${date:yyyy-MM}/${app.name}-%d{yyyy-MM-dd}.log.gz">
            <PatternLayout pattern="${file.pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            </Policies>
            <DefaultRolloverStrategy max="3">
                <!--
                Nested conditions: the inner condition is only evaluated on files
                for which the outer conditions are true.
                -->
                <Delete basePath="${logs.dir}" maxDepth="2" testMode="${script.test.mode}">
                    <IfFileName glob="*/${app.name}*.log.gz">
                        <IfLastModified age="90d">
                            <IfAny>
                                <IfAccumulatedFileCount exceeds="10"/>
                            </IfAny>
                        </IfLastModified>
                    </IfFileName>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>

    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="CONSOLE"/>
            <AppenderRef ref="LOG"/>
        <AppenderRef ref='GELF' />
        </Root>

        <Logger name="xxx.project" level="${log.level}"/>
        <Logger name="org.hibernate" level="${framework.log.level}"/>
        <Logger name="com.zaxxer" level="${framework.log.level}"/>
        <!--<Logger name="org.hibernate" level="ALL"/>-->
        <Logger name="org.reflections" level="OFF"/>
    <!-- show executed queries -->
        <!--<Logger name="org.hibernate.SQL" level="DEBUG"/>-->
        <!-- show query params -->
    <!--
    <Logger name="org.hibernate.type.descriptor.sql" level="TRACE"/> -->
        <!--
        <AsyncLogger name="az.sanco.projects.ais.server.filter" additivity="false" level="${log.level}">
            <AppenderRef ref="AUDITOR"/>
        </AsyncLogger> -->
    </Loggers>
</Configuration>

Tomcat版本:9.0

Java版本:1.8

log4j2版本:2.14.0

java log4j2 tomcat9
2个回答
1
投票

您的

457e2f02
 的随机名称 
LoggerContext
表明您的所有应用程序都使用单个上下文。当您的应用程序之一停止时,将在上下文中调用
stop
方法,并且无法记录更多消息。同时,重新加载的应用程序会为自己创建一个上下文。

如果您直接在应用程序中使用 Log4j API,但没有为应用程序提供

log4j-api
的副本,则可能会发生这种情况:在这种情况下,共享 Tomcat 类加载器中的
LogManager
类将被使用所有应用程序。

尝试将

log4j-api.jar
添加到您的应用程序中。


1
投票

实际上@PiotrP.Karwasz 的答案解决了

log4j
问题。但不解决我们的问题。如果我们应用他的答案,那么我们应该将所有
log4j-core
log4j-api
log4j-web
jar 移动到每个应用程序
WEB-INF\lib
文件夹,这不是有效的方法。因为我们有近 20 个模块,在这种情况下,我们将 jar 复制到所有这些模块并占用更多资源。根据log seperation文档,我们不应该为此要求做任何进一步的配置。 Log4j 上下文选择器应为每个
war
模块选择上下文 auto。但在实践中我们发现它不能正常工作。也许是错误,或者可能是我们没有正确配置。我从文档中选择了第三个选项
org.apache.logging.log4j.core.selector.JndiContextSelector
。这解决了我们的问题。我们将
log4j-core
log4j-api
log4j-web
jar 保留在公共路径中,并且我们的每个模块都使用这些 jar。现在,当我们重新部署其中一个模块时,
log4j
可以正常工作。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.