I'm working with some software which spits out to the following logfile:
{"message":"logger controller initialised","@timestamp":"2018-09-15T09:33:25.709+01:00","logger_name":"com.hidden.controller.LoggerController","thread_name":"JavaFX Application Thread","level":"DEBUG"}
{"message":"parsing history log data to display","@timestamp":"2018-09-15T09:33:25.877+01:00","logger_name":"com.hidden.controller.LoggerController","thread_name":"JavaFX Application Thread","level":"DEBUG"}
When I'm trying to parse this json file using Gson to a LogRowModel[] it is spitting out various errors around the format of the json, for example:
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
I am writing my file using logback/logstash json encoder using the following setup:
<configuration>
<timestamp key="time" datePattern="yyyy-MM-dd'_'HH-mm-ss.SSS"/>
<appender name="RootSiftAppender" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<Key>test</Key>
<DefaultValue>logfile</DefaultValue>
</discriminator>
<sift>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>src\\main\\resources\\${test}.json</File>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<message/>
<timestamp/>
<loggerName/>
<threadName/>
<logLevel/>
</providers>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>${test_name}.%i.json</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>100</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>50MB</MaxFileSize>
</triggeringPolicy>
</appender>
</sift>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%n %d{HH:mm:ss} %thread %level %logger{0} %msg</pattern>
</encoder>
</appender>
<root level="RootSiftAppender">
<appender-ref ref="RootSiftAppender"/>
</root>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
How can I parse my json file into an array of this:
@Data
@Slf4j
public class LogRowModel {
@JsonProperty("@timestamp") private final String timestamp;
@JsonProperty("message") private final String message;
@JsonProperty("logger_name") private final String logger;
@JsonProperty("level") private final String level;
@JsonProperty("thread_name") private final String thread;
}
Here is my current code which is throwing the error (I assume the fault lies with the json format, scratching my head on how to format it better)
Type collectionType = new TypeToken<Collection<LogRowModel>>(){}.getType();
Collection<LogRowModel> enums = new Gson().fromJson(new FileReader(new File("src/main/resources/logfile.json")), collectionType);
or how can I make my logger output in a much better json array format?
Thanks.
example code of how I achieved what I needed using Gson's JsonStreamParser to process each root node object in turn.
private void buildHistoryData() {
if (isLogFileEmpty()) return;
history.clear();
Gson gson = new GsonBuilder().create();
try {
JsonStreamParser parser = new JsonStreamParser(new FileReader(LOG_FILE));
while (parser.hasNext()) {
final LogRowModel currentRow = gson.fromJson(parser.next(), LogRowModel.class);
if (currentFilter == LogFilter.ALL) history.add(currentRow);
else if (currentRow.getLevel().equalsIgnoreCase(currentFilter.getLevel()))
history.add(currentRow);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}