2016-07-28 2 views
0

Я пытаюсь сохранить свои журналы в файлах JSON с помощью Log4J (2.6.2). Я использую JsonLayout в RollingFileAppender, и он работает нормально, пока я не пытаюсь добавить файл, который уже был написан ранее.Log4J - JsonLayout и RollingFileAppender генерируют недействительные JSON

Вот мой код для создания макета и Appender:

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 
    } 
] 

I затем закройте мой 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, установить полный = ЛОЖЬ (у вас есть это, как верно в вашем образце), который будет печатать его без «[» и «]». Затем вы можете добавить эти символы перед вызовом GSON (так как файл не будет иметь массив).
  2. Создайте свой собственный JSONLayout (вам нужно расширить AbstractStringLayout), используя что-то простое, например org.json: json или GSON, чтобы получить строку для файла.
Смежные вопросы