log4j2 基于命令行参数的动态文件名

我们使用一个相当简单的 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

之后,日志记录继续输出到标准输出,并且所需的日志文件保持为空。


有人知道我做错了什么吗?


胡说叔叔
浏览 209回答 2
2回答

皈依舞

您不需要编程配置来执行您想要的操作,并且我强烈建议您不要使用它,因为这会使您的代码依赖于 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。希望这可以帮助!

jeck猫

尝试这个&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;*&nbsp;&nbsp; &nbsp; &nbsp;* @param logType 0 = console, 1 = file&nbsp; &nbsp; &nbsp;* @param logFile&nbsp; &nbsp; &nbsp;* @param level&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; private void divertLogging(int logType, String logFile, Level level) {&nbsp; &nbsp; &nbsp; &nbsp; ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();&nbsp; &nbsp; &nbsp; &nbsp; AppenderComponentBuilder appenderBuilder;&nbsp; &nbsp; &nbsp; &nbsp; if (logType == 0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);&nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; appenderBuilder = builder.newAppender("File", "FILE").addAttribute("fileName", logFile).addAttribute("append", "false");&nbsp; &nbsp; &nbsp; &nbsp; appenderBuilder.add(builder.newLayout("PatternLayout")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));&nbsp; &nbsp; &nbsp; &nbsp; builder.add(appenderBuilder);&nbsp; &nbsp; &nbsp; &nbsp; if (logType == 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; builder.add(builder.newRootLogger(level).add(builder.newAppenderRef("File")));&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; builder.writeXmlConfiguration(System.out);&nbsp; &nbsp; &nbsp; &nbsp; } catch (IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; BuiltConfiguration configuration = builder.build();&nbsp; &nbsp; &nbsp; &nbsp; Configurator.initialize(configuration);&nbsp; &nbsp; &nbsp; &nbsp; ((LoggerContext)LogManager.getContext(false)).updateLoggers(configuration);&nbsp; &nbsp; &nbsp; &nbsp; if (logType == 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; configuration.getAppender("File").start();&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; Log4j2Test test = new Log4j2Test();&nbsp; &nbsp; &nbsp; &nbsp; test.divertLogging(0, null, Level.ALL);&nbsp; &nbsp; &nbsp; &nbsp; logger.error("Log to console 1");&nbsp; &nbsp; &nbsp; &nbsp; test.divertLogging(1, "C:\\Java\\test\\output\\test.log", Level.ALL);&nbsp; &nbsp; &nbsp; &nbsp; logger.error("Log to file 2");&nbsp; &nbsp; &nbsp; &nbsp; test.divertLogging(0, null, Level.ALL);&nbsp; &nbsp; &nbsp; &nbsp; logger.error("Log to console 3");&nbsp; &nbsp; &nbsp; &nbsp; test.divertLogging(1, "C:\\Java\\test\\output\\test.log", Level.ALL);&nbsp; &nbsp; &nbsp; &nbsp; logger.error("Log to file 4");&nbsp; &nbsp; }为什么我的答案被否决了?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java