亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

log4j2 基于命令行參數的動態文件名

log4j2 基于命令行參數的動態文件名

胡說叔叔 2023-08-16 17:23:01
我們使用一個相當簡單的 log4j2.xml 配置文件來記錄到標準輸出。然而,在某些情況下,我們希望在應用程序啟動后以編程方式更改此配置,以使用在命令行上移交的日志文件。為此,我按照 log4j2 主頁上的建議編寫了以下方法static void divertLogging(String logFile, Level level) {    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();    AppenderComponentBuilder appenderBuilder         = builder.newAppender("File", "FILE").addAttribute("fileName", logFile).addAttribute("append", "false");    appenderBuilder.add(builder.newLayout("PatternLayout")        .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));    builder.add(appenderBuilder);    builder.add(builder.newRootLogger(level).add(builder.newAppenderRef("File")));    try {        builder.writeXmlConfiguration(System.out);    } catch (IOException e) {        throw new ApplicationException(e);    }    BuiltConfiguration configuration = builder.build();    Configurator.initialize(configuration);    ((LoggerContext)LogManager.getContext(false)).updateLoggers(configuration);}我們得到以下輸出<?xml version="1.0" ?><Configuration>    <Appenders>        <FILE name="File" fileName="test.log" append="false">            <PatternLayout pattern="%d [%t] %-5level: %msg%n%throwable"/>        </FILE>    </Appenders>    <Loggers>        <Root level="INFO">            <AppenderRef ref="File"/>        </Root>    </Loggers></Configuration>然后是日志消息ERROR Attempted to append to non-started appender File之后,日志記錄繼續輸出到標準輸出,并且所需的日志文件保持為空。有人知道我做錯了什么嗎?
查看完整描述

2 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

您不需要編程配置來執行您想要的操作,并且我強烈建議您不要使用它,因為這會使您的代碼依賴于 log4j2 實現而不是其公共接口。

要在運行時動態更改文件,您可以將與LookupRoutingAppender一起使用。

這是 log4j2 配置示例:

<?xml version="1.0" ?>

<Configuration>

? ? <Appenders>

? ? ? ? <Routing name="myAppender">

? ? ? ? ? ? <Routes pattern="$${main:0}">

? ? ? ? ? ? ? ? <!-- This route is chosen if there is no value for main argument 0 -->

? ? ? ? ? ? ? ? <Route key="$${main:0}">

? ? ? ? ? ? ? ? ? ? <File

? ? ? ? ? ? ? ? ? ? ? ? fileName="logs/default.log"

? ? ? ? ? ? ? ? ? ? ? ? name="myAppender-default">

? ? ? ? ? ? ? ? ? ? ? ? <PatternLayout pattern="%d [%t] %-5level: %msg%n%throwable"/>

? ? ? ? ? ? ? ? ? ? </File>

? ? ? ? ? ? ? ? </Route>

? ? ? ? ? ? ? ? <!-- This route is chosen if there is a value for main argument 0 -->

? ? ? ? ? ? ? ? <Route>

? ? ? ? ? ? ? ? ? ? <File

? ? ? ? ? ? ? ? ? ? ? ? fileName="logs/${main:0}.log"

? ? ? ? ? ? ? ? ? ? ? ? name="myAppender-${main:0}">

? ? ? ? ? ? ? ? ? ? ? ? <PatternLayout pattern="%d [%t] %-5level: %msg%n%throwable"/>

? ? ? ? ? ? ? ? ? ? </File>

? ? ? ? ? ? ? ? </Route>

? ? ? ? ? ? </Routes>

? ? ? ? </Routing>

? ? </Appenders>

? ? <Loggers>

? ? ? ? <Root level="INFO">

? ? ? ? ? ? <AppenderRef ref="myAppender"/>

? ? ? ? </Root>

? ? </Loggers>

</Configuration>

以下是一些用于生成日志的示例 Java 代碼:


import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

import org.apache.logging.log4j.ThreadContext;

import org.apache.logging.log4j.core.lookup.MainMapLookup;


public class SomeClass {


? ? private static final Logger LOG = LogManager.getLogger();? ?


? ? public static void main(String[] args){

? ? ? ? MainMapLookup.setMainArguments(args);


? ? ? ? LOG.info("This should appear in default.log");


? ? ? ? args = new String[]{"specialFile"};

? ? ? ? MainMapLookup.setMainArguments(args);

? ? ? ? LOG.info("This should appear in specialFile.log");

? ? }

}

當執行上述代碼而不傳遞程序參數時,會生成 2 個日志,每個日志有 1 個條目。default.log 包含第一個日志條目,specialFile.log 包含第二個日志條目。如果您傳遞程序參數,它將用作日志文件名,在這種情況下,default.log 中不會出現任何條目 - 如第二個日志所示,其中我們通過創建新數組來模擬傳遞單個參數String。


希望這可以幫助!


查看完整回答
反對 回復 2023-08-16
?
jeck貓

TA貢獻1909條經驗 獲得超7個贊

嘗試這個


    /**

     * 

     * @param logType 0 = console, 1 = file

     * @param logFile

     * @param level

     */

    private void divertLogging(int logType, String logFile, Level level) {

        ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();


        AppenderComponentBuilder appenderBuilder;


        if (logType == 0)

            appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);

        else

            appenderBuilder = builder.newAppender("File", "FILE").addAttribute("fileName", logFile).addAttribute("append", "false");


        appenderBuilder.add(builder.newLayout("PatternLayout")

            .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));


        builder.add(appenderBuilder);

        if (logType == 1)

            builder.add(builder.newRootLogger(level).add(builder.newAppenderRef("File")));


        try {

            builder.writeXmlConfiguration(System.out);

        } catch (IOException e) {

            e.printStackTrace();

        }


        BuiltConfiguration configuration = builder.build();


        Configurator.initialize(configuration);

        ((LoggerContext)LogManager.getContext(false)).updateLoggers(configuration);

        if (logType == 1)

            configuration.getAppender("File").start();

    }


    public static void main(String[] args) {

        Log4j2Test test = new Log4j2Test();

        test.divertLogging(0, null, Level.ALL);

        logger.error("Log to console 1");

        test.divertLogging(1, "C:\\Java\\test\\output\\test.log", Level.ALL);

        logger.error("Log to file 2");

        test.divertLogging(0, null, Level.ALL);

        logger.error("Log to console 3");

        test.divertLogging(1, "C:\\Java\\test\\output\\test.log", Level.ALL);

        logger.error("Log to file 4");

    }

為什么我的答案被否決了?


查看完整回答
反對 回復 2023-08-16
  • 2 回答
  • 0 關注
  • 302 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號