以编程方式配置时,filePattern 中存在 : 字符会导致 RollingFileAppender (log4j2) 出现 Illegal Char 错误

The presence of : character in filePattern causes Illegal Char error in RollingFileAppender (log4j2) when configuring programatically

在log4j2.xml定义RollingFileAppender时,它工作正常。以编程方式抛出错误。 XML 文件 -

  <RollingFile name="LogToRollingFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM-dd-HH-mm}/app_%d{yyyy-MM-dd-HH-mm}_%i.log">

Java 试图复制相同的代码。

final RollingFileAppender rollingFileAppender = RollingFileAppender.newBuilder()
                    .setName("RollingFileAppenderFor"+fileName)
                    .withFileName("logs/"+ fileName+".log")
                    .withFilePattern("logs/$${date:yyyy-MM-dd-HH-mm}/"+ fileName +"-%d{yyyy-MM-dd-HH-mm}-%i.log.gz")
                    .withAppend(true)
                    .setConfiguration(config)
                    .setLayout(layout)
                    .withPolicy(CompositeTriggeringPolicy.createPolicy(timeBasedTriggeringPolicy,sizeBasedTriggeringPolicy))
                    .withStrategy(defaultRolloverStrategy)
                    .build();

导致以下错误。

2022-04-11 23:20:55,164 main ERROR An exception occurred processing Appender RollingFileAppenderForMephisto java.nio.file.InvalidPathException: Illegal char <:> at index 11: logs${date:yyyy-MM-dd-HH-mm}
    at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
    at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
    at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
    at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
    at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:232)
    at java.base/java.io.File.toPath(File.java:2387)
    at org.apache.logging.log4j.core.appender.rolling.AbstractRolloverStrategy.getEligibleFiles(AbstractRolloverStrategy.java:121)
    at org.apache.logging.log4j.core.appender.rolling.AbstractRolloverStrategy.getEligibleFiles(AbstractRolloverStrategy.java:95)
    at org.apache.logging.log4j.core.appender.rolling.AbstractRolloverStrategy.getEligibleFiles(AbstractRolloverStrategy.java:86)
    at org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy.purgeAscending(DefaultRolloverStrategy.java:414)
    at org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy.purge(DefaultRolloverStrategy.java:401)
    at org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy.rollover(DefaultRolloverStrategy.java:530)
    at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.rollover(RollingFileManager.java:502)
    at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.rollover(RollingFileManager.java:392)
    at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.checkRollover(RollingFileManager.java:308)
    at org.apache.logging.log4j.core.appender.RollingFileAppender.append(RollingFileAppender.java:311)
    at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:161)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:134)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:125)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:89)
    at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:542)
    at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:500)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:483)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:417)
    at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82)
    at org.apache.logging.log4j.core.Logger.log(Logger.java:161)
    at org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2205)
    at org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2159)
    at org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2142)
    at org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2017)
    at org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1983)
    at org.apache.logging.log4j.spi.AbstractLogger.log(AbstractLogger.java:1652)
    at mcoc.ChampionLogger.addLoggerWithModificationAndLog(ChampionLogger.java:137)
    at mcoc.Test3.main(Test3.java:8)

有什么我可以做的吗,这里有 : 字符的替代品吗?

请阅读Log4j difference between dollar and percent patterns in layout了解更多详情。并非原始答案中的所有声明都是事实正确的(并且可能导致令人惊讶的行为)。


$ 字符将转义第二个美元字符并使其成为输出中的文字美元字符。

将日期格式设置为 %d{...} 而不是 $${date:...}(您也可以尝试 ${date:...},注意单美元):

  <RollingFile
      name="LogToRollingFile"
      fileName="logs/app.log"
      filePattern="logs/%d{yyyy-MM-dd-HH-mm}/app_%d{yyyy-MM-dd-HH-mm}_%i.log">

至于为什么documentation在一个例子中混合了%d${date:},我不知道。