具有不同log4j2.xml的两个应用程序正在尝试登录相同的日志文件

时间:2017-03-10 06:54:22

标签: java logging configuration log4j log4j2

我正在运行两个应用程序,A和B. B对A有运行时依赖性。两个应用程序都有自己的log4j2.xml文件,其中包含日志文件名和其他信息。

B有一些预安装脚本,由'root'用户在A之前执行。它创建自己的日志文件b_log.log当A启动时,它尝试登录b_log.log而不是创建自己的日志文件。 A由不同的用户'a_user'启动。所以A得到'权限被拒绝'错误,因为它无法访问并登录'root'创建的b_log.log。两个日志文件都使用RollingRandomAccessFile appender。

如何让两个应用程序都登录到单独的日志文件中?提供单独的log4j2.xml无效。

应用程序A的log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <RollingRandomAccessFile name="ApplicationFile" fileName="${sys:logPath}/log_a.log"
                     filePattern="${sys:logPath}/log_a.log".%d{yyyy-MM-dd-HH}">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%-5level] (%t) %X{sessionId} %c{1}: %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="ApplicationFile"/>
        </Root>

        <!-- Loggers explicitly defined here, so their levels could be adjusted in runtime via JMX -->
        <Logger name="com.xyz.a.package" level="INFO" />
    </Loggers>
</Configuration>

应用程序B的log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <RollingRandomAccessFile name="LogB" fileName="${sys:logPath}/log_b.log"
                     filePattern="$${sys:logPath}/log_b.log.%d{yyyy-MM-dd-HH}">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%-5level] (%t) %X{sessionId} %c{1}: %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
            </Policies>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <Logger name="com.xyz.b.package" level="INFO" additivity="false">
            <AppenderRef ref="LogB"/>
        </Logger>
    </Loggers>
</Configuration>

应用程序A无法访问b_log的例外:


    2017-03-12 07:42:37,197 main ERROR Cannot access RandomAccessFile java.io.FileNotFoundException: /app/env/Service/var/output/logs/log_b.log (Permission denied) java.io.FileNotFoundException: /app/env/Service/var/output/logs/log_b.log (Permission denied)
            at java.io.RandomAccessFile.open0(Native Method)
            at java.io.RandomAccessFile.open(RandomAccessFile.java:316)
            at java.io.RandomAccessFile.(RandomAccessFile.java:243)
            at java.io.RandomAccessFile.(RandomAccessFile.java:124)
            at org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager$RollingRandomAccessFileManagerFactory.createManager(RollingRandomAccessFileManager.java:176)
            at org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager$RollingRandomAccessFileManagerFactory.createManager(RollingRandomAccessFileManager.java:149)
            at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:73)
            at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:81)
            at org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileManager.getRollingRandomAccessFileManager(RollingRandomAccessFileManager.java:82)
            at org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender.createAppender(RollingRandomAccessFileAppender.java:207)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:132)
            at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:918)
            at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:858)
            at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:850)
            at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:479)
            at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:219)
            at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:231)
            at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:496)
            at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:566)
            at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:582)
            at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:217)
            at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
            at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
            at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
            at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
            at org.apache.logging.log4j.jul.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:34)
            at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
            at org.apache.logging.log4j.jul.LogManager.getLogger(LogManager.java:89)
            at java.util.logging.LogManager.demandLogger(LogManager.java:551)
            at java.util.logging.Logger.demandLogger(Logger.java:455)
            at java.util.logging.Logger.getLogger(Logger.java:502)
            at com.sun.jmx.remote.util.ClassLogger.(ClassLogger.java:55)
            at sun.management.jmxremote.ConnectorBootstrap.(ConnectorBootstrap.java:846)
            at sun.management.Agent.startAgent(Agent.java:257)
            at sun.management.Agent.startAgent(Agent.java:447)

    2017-03-12 07:42:37,209 main ERROR Unable to invoke factory method in class class org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender for element RollingRandomAccessFile. java.lang.reflect.InvocationTargetException
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

1 个答案:

答案 0 :(得分:1)

您可以共享相同的Log4j2配置文件,并通过将文件appender路径(的一部分)作为系统属性并为每个应用程序提供不同的属性值来记录到不同的日志文件。

一个简单的例子如下:

<Appenders>
  <File name="ApplicationLog" fileName="${sys:logPath}/app.log"/>
</Appenders>

有关如何在配置文件中使用Lookup的信息,请参见Property Substitution页面的Configuration部分。

更新: 请注意,如果日志记录目录是由以root身份运行的进程创建的,则以其他用户身份运行的其他进程可能无权在该目录中创建文件...

但这不是Log4j2问题。您需要确保目标目录具有正确的权限。

更新2: 总结问题:应用程序B首先运行并创建b_log.log。下一个应用A运行。您指定了不同的Log4j2配置,但由于某种原因,应用程序A从应用程序B 中选择了Log4j2配置,而应用程序A也尝试(错误地)登录到b_log.log。由于权限,此操作失败。问题不在于A 无法写入b_log.log,但它不应该尝试写入该文件:它的配置错误。

如果以上是正确的,那么问题是如何防止第二次申请&#34; A&#34;从挑错配置。您可以通过使用系统属性-Dlog4j.configurationFile=path/to/log4j2.xml启动第二个应用程序来确切地告诉它要使用的配置文件。