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

标签 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 附加程序。

如何使两个应用程序登录到单独的日志文件中?提供单独的 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)

最佳答案

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

一个简单的例子如下:

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

有关如何在配置文件中使用查找的信息可以在 Property Substitution 中找到。 Configuration 部分页。

<小时/>

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

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

<小时/>

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

如果上述正确,那么问题是如何防止第二个应用程序“A”选择错误的配置。您可以通过使用系统属性 -Dlog4j.configurationFile=path/to/log4j2.xml 启动第二个应用程序来完成此操作,以准确告诉它要使用哪个配置文件。

关于java - 具有不同 log4j2.xml 的两个应用程序正在尝试登录到同一日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42712130/

相关文章:

java - 使用java无法找到selenium中的元素错误

java - 日志文件动态监控

python - 解析 Nginx 日志

java - 是否可以使用 Guice 中的 Multibinder 根据应用程序配置构建动态集?

java - 整数溢出klocwork分析

java - Spring security Saml - SP和IDP的时间差

ruby-on-rails - 如何从 Rails 事件记录中返回查询,以便我可以将它们传回客户端日志控制台

php - 使用 SQLite 进行配置管理

configuration - Ansible,找不到角色错误

java - 在 Akka Streams Sink 之后获取原始元素的引用?