簡體   English   中英

Log4j2 初始化后配置 FileAppender

[英]Configure FileAppender after Log4j2 Initialization

我在為log4j2記錄器配置新的FileAppender遇到問題。 問題是我只知道我應該在應用程序啟動附加我的日志的文件的路徑,所以我嘗試按照這里的這些說明log4j2初始化后修改原始配置。

我已經閱讀了很多關於堆棧溢出類似問題的答案,但其中大部分是針對早期的log4j版本,並且無法工作,因為他們現在已經將面向配置的插件實現到 log4j 本身中。

應用程序成功創建了日志文件,但不會向其中寫入任何內容 我故意將該測試日志消息放在ERROR級別,以便我可以驗證它與日志級別閾值或其他內容無關。

我對 log4j2 配置有點陌生,此時感覺有點迷茫。

我的log4j2.xml文件(非常基本的)如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Properties>
        <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
             <PatternLayout pattern="${PATTERN}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

此外,這是應該添加新FileAppender

public static void initLogFile(String path, Level level) {
    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    final Configuration config = ctx.getConfiguration();
    Layout layout = PatternLayout.createDefaultLayout(config);
    Appender appender = FileAppender.createAppender(path, "false", "true",
            "RollingFile", "true", "false", "false", "8000", null, null,
            "false", null, config);
    appender.start();
    config.addAppender(appender);
    AppenderRef ref = AppenderRef.createAppenderRef("RollingFile", null,
            null);
    AppenderRef[] refs = new AppenderRef[] { ref };
    LoggerConfig loggerConfig = LoggerConfig.createLogger("false", level,
            "org.apache.logging.log4j", "true", refs, null, config, null);
    loggerConfig.addAppender(appender, null, null);
    config.addLogger("org.apache.logging.log4j", loggerConfig);
    ctx.updateLoggers();
    System.out.println("Logger initialized");
}

還有我的Main方法,它做的第一件事就是嘗試更改記錄器配置以寫入我想要的文件:

static final Logger log = LogManager.getLogger(Main.class.getName());
  public static void main( String[] args )
    {
        // Init
        System.out.println("Initializing logger");
        Utils.initLogFile("C:/Users/Jorge/Desktop/logtest/test.log", Level.DEBUG);

        log.error("test error message");

        ...
 }

你的意思是你只知道應用程序啟動后的路徑? 無論如何,您應該始終能夠使用查找來確定文件路徑。 如果路徑被指定為應用程序的參數之一,您應該能夠使用主參數查找。

需要明確的是,您的配置應該類似於:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
    <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
         <PatternLayout pattern="${PATTERN}"/>
    </Console>
    <File name="file" fileName="${main:--logFile}">
         <PatternLayout pattern="${PATTERN}"/>
    </File> 
</Appenders>
<Loggers>
    <Logger name="org.apache.logging.log4j" level="${main:--level}">
       <AppenderRef ref="file"/>
    </Logger>
    <Root level="debug">
        <AppenderRef ref="Console" />
    </Root>
</Loggers>

請注意,我已經配置了一個文件附加程序。 您的示例代碼正在創建一個文件附加程序,但出於某種原因將其命名為“RollingFile”。

我接受這個答案,因為它與問題的標題嚴格相關。 如果您正在查看這篇文章以尋求幫助,您應該花點時間閱讀 @rgoers 的回答,因為它可能正是您要找的。

所以這就是我最終做到的。 將現有的空新記錄器配置到我的log4j2.xml文件中(因為我不想在運行時創建一個新記錄器),我將在運行時修改它。

我的原始代碼的問題是記錄器的名稱。 如果您查看原始帖子,我正在創建一個名為“org.apache.logging.log4j”的新 appender。

在我的主類上,當我檢索我要記錄的記錄器時,我正在獲取我的主類所在的包的默認記錄器 ( com.jorge.myapp.business )。 因此,這個記錄器接收了所有的日志請求,而我創建的新的( org.apache.logging.log4j )沒有接收到任何請求。 這就是為什么它不會將任何內容記錄到我輸入的文件中,因為所有記錄請求都轉到其他記錄器( com.jorge.myapp.business )。

我希望這對某人有所幫助,解釋起來有點混亂......下面是關於我的類和配置文件的更多信息:

修改配置文件log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Properties>
        <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
             <PatternLayout pattern="${PATTERN}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" />
        </Root>
        <Logger name="com.jorge.myapp.business" level="debug">
        </Logger>

    </Loggers>
</Configuration>

這是初始化方法,它從 xml 文件中檢索當前的log4j2配置並修改現有的記錄器,添加一個新的文件附加程序。

public static void initLogFile(String path, Level level){

    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    final Configuration config = ctx.getConfiguration();

    Layout layout = PatternLayout.createLayout(Constants.LOG_PATTERN, null, config, null, null, false, false, null, null);
    Appender appender = FileAppender.createAppender(path, "true", "true", "File", "true",
        "false", "false", null, layout, null, "false", null, config);
    appender.start();
    config.addAppender(appender);
    AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
    AppenderRef[] refs = new AppenderRef[] {ref};
    LoggerConfig loggerConfig = config.getLoggerConfig("com.jorge.myapp.business");
    loggerConfig.addAppender(appender, null, null);
    ctx.updateLoggers();
}

我使用的一些常量Constants.java類):

public static final String LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss} [%-5level] MyApp - %msg%n";

正如@rgoers 指出的那樣,可以在此處找到有關 Log4j2 如何在“幕后”實際工作的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM