2016-07-28 164 views
0

我想使用Log4J(2.6.2)将日志存储在JSON文件中。我在RollingFileAppender中使用了JsonLayout,只要我不试图附加到之前已写入的文件,它就能正常工作。Log4J - JsonLayout和RollingFileAppender生成无效的JSON

这是我设立的布局和追加程序代码:

Layout<?> layout = JsonLayout.createLayout(config, false, false, false, true, false, true, "[", "]", Charset.defaultCharset()); 

String appenderFileName = "mylogfile-latest.log.json"; 
String appenderFilePattern = "mylogfile-%i.log.json"; 
String appenderName = "MyAppender"; 
Appender appender = RollingFileAppender.createAppender(appenderFileName, appenderFilePattern, "true", appenderName, "true", "256", "true", 
     SizeBasedTriggeringPolicy.createPolicy(this.configuration.getLogMaxSize().toString()), 
     null, layout, null, "false", "false", null, config); 

正如我所说的,它的正常工作的第一次,我在我的日志文件中写入:

[ 
    { 
    "timeMillis" : 1469620840442, 
    "thread" : "SimpleAsyncTaskExecutor-43", 
    "level" : "ERROR", 
    "loggerName" : "MyLogger", 
    "message" : "my log message", 
    "endOfBatch" : false, 
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", 
    "threadId" : 243, 
    "threadPriority" : 5 
    } 
    , { 
    "timeMillis" : 1469620840442, 
    "thread" : "SimpleAsyncTaskExecutor-43", 
    "level" : "DEBUG", 
    "loggerName" : "MyLogger", 
    "message" : "my log message", 
    "endOfBatch" : false, 
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", 
    "threadId" : 243, 
    "threadPriority" : 5 
    } 
] 

我然后关闭我的appender等...并重新启动我的应用程序,当我正在写入新的日志到这个现有的文件,这里是我得到的:

[ 
{ 
    "timeMillis" : 1469620840442, 
    "thread" : "SimpleAsyncTaskExecutor-43", 
    "level" : "ERROR", 
    "loggerName" : "MyLogger", 
    "message" : "my log message", 
    "endOfBatch" : false, 
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", 
    "threadId" : 243, 
    "threadPriority" : 5 
} 
, { 
    "timeMillis" : 1469620840442, 
    "thread" : "SimpleAsyncTaskExecutor-43", 
    "level" : "DEBUG", 
    "loggerName" : "MyLogger", 
    "message" : "my log message", 
    "endOfBatch" : false, 
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", 
    "threadId" : 243, 
    "threadPriority" : 5 
} 

] 
{ 
    "timeMillis" : 1469620840490, 
    "thread" : "SimpleAsyncTaskExecutor-43", 
    "level" : "ERROR", 
    "loggerName" : "MyLogger", 
    "message" : "my log message", 
    "endOfBatch" : false, 
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", 
    "threadId" : 245, 
    "threadPriority" : 5 
    } 
    , { 
    "timeMillis" : 1469620840492, 
    "thread" : "SimpleAsyncTaskExecutor-43", 
    "level" : "DEBUG", 
    "loggerName" : "MyLogger", 
    "message" : "my log message", 
    "endOfBatch" : false, 
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", 
    "threadId" : 245, 
    "threadPriority" : 5 
    } 

] 

由于Gson将无法从此文件创建List,因此此问题导致无法解析日志。

你对如何解决这个问题没有任何想法,没有做一个蹩脚的黑客删除额外]并用逗号代替它?

谢谢!

回答

0

由于没有其他的解决办法是令人满意的,我结束了使用正则表达式来代替无效字符...

这是相当安全的,因为它会检查,如果它不是在两个双引号之间,但它不是理想的解决方案显然是:

String content = new String(Files.readAllBytes(Paths.get(pathToLogFile))); 
content = content.replaceAll("(\\}\\R{2}\\]\\R\\{)(?=(?:(?:\\.|[^\"\\\\])*\"(?:\\.|[^\"\\\\])*\")*(?:\\.|[^\"\\\\])*)", "}\n, {"); 
Files.write(Paths.get(pathToLogFile), content.getBytes()); 
1

JSONLayout这样做的原因是为了创建一个“格式良好”的JSON文档。您需要将每个文档放在它自己的文件中(带有开始和结束括号),因为这是真实的,这不是这里的情况。

你有两个选择:

  1. 对于JSONLayout,一套完整= FALSE(您有它的样品中为真),将它打印出来没有“[”和“]”。然后你可以在调用GSON之前自己添加这些字符(因为该文件实际上没有数组)。
  2. 使用org.json这样简单的命令创建自己的JSONLayout(您需要扩展AbstractStringLayout):json或GSON来获取文件的字符串。