@Test public void formatProducesExpectedJsonData() throws Exception { LogRecord record = new LogRecord(Level.INFO, "message"); record.setMillis(12345_678); record.setLoggerName("logger"); LogContext context = new LogContext(Collections.singletonMap("traceId", "abcdef")); String logLine = context.execute(() -> formatter.format(record)); assertThat(logLine, endsWith(System.lineSeparator())); JsonData data = new Gson().fromJson(logLine, JsonData.class); assertEquals("INFO", data.severity); assertEquals(12345, data.timestamp.seconds); assertEquals(678_000_000, data.timestamp.nanos); assertEquals(Thread.currentThread().getName(), data.thread); assertEquals("logger: message", data.message); assertEquals("abcdef", data.traceId); }
@Override public String format(LogRecord record) { Instant timestamp = Instant.ofEpochMilli(record.getMillis()); StringWriter out = new StringWriter(); try (JsonWriter writer = new JsonWriter(out)) { writer.setSerializeNulls(false); writer.setHtmlSafe(false); writer.beginObject(); writer.name("timestamp") .beginObject() .name("seconds").value(timestamp.getEpochSecond()) .name("nanos").value(timestamp.getNano()) .endObject(); writer.name("severity").value(severity(record.getLevel())); writer.name("thread").value(Thread.currentThread().getName()); writer.name("message").value(formatMessage(record)); LogContext logContext = LogContext.current(); if (logContext != null) { logContext.forEach((name, value) -> { try { writer.name(name); if (value == null) { writer.nullValue(); } else if (value instanceof Boolean) { writer.value((boolean) value); } else if (value instanceof Number) { writer.value((Number) value); } else { writer.value(value.toString()); } } catch (IOException e) { throw new AssertionError(e); } }); } writer.endObject(); } catch (IOException e) { throw new AssertionError(e); } out.append(System.lineSeparator()); return out.toString(); }
JsonFormatter extends Formatter { @Override public String format(LogRecord record) { Instant timestamp = Instant.ofEpochMilli(record.getMillis()); StringWriter out = new StringWriter(); try (JsonWriter writer = new JsonWriter(out)) { writer.setSerializeNulls(false); writer.setHtmlSafe(false); writer.beginObject(); writer.name("timestamp") .beginObject() .name("seconds").value(timestamp.getEpochSecond()) .name("nanos").value(timestamp.getNano()) .endObject(); writer.name("severity").value(severity(record.getLevel())); writer.name("thread").value(Thread.currentThread().getName()); writer.name("message").value(formatMessage(record)); LogContext logContext = LogContext.current(); if (logContext != null) { logContext.forEach((name, value) -> { try { writer.name(name); if (value == null) { writer.nullValue(); } else if (value instanceof Boolean) { writer.value((boolean) value); } else if (value instanceof Number) { writer.value((Number) value); } else { writer.value(value.toString()); } } catch (IOException e) { throw new AssertionError(e); } }); } writer.endObject(); } catch (IOException e) { throw new AssertionError(e); } out.append(System.lineSeparator()); return out.toString(); } }
JsonFormatter extends Formatter { @Override public String format(LogRecord record) { Instant timestamp = Instant.ofEpochMilli(record.getMillis()); StringWriter out = new StringWriter(); try (JsonWriter writer = new JsonWriter(out)) { writer.setSerializeNulls(false); writer.setHtmlSafe(false); writer.beginObject(); writer.name("timestamp") .beginObject() .name("seconds").value(timestamp.getEpochSecond()) .name("nanos").value(timestamp.getNano()) .endObject(); writer.name("severity").value(severity(record.getLevel())); writer.name("thread").value(Thread.currentThread().getName()); writer.name("message").value(formatMessage(record)); LogContext logContext = LogContext.current(); if (logContext != null) { logContext.forEach((name, value) -> { try { writer.name(name); if (value == null) { writer.nullValue(); } else if (value instanceof Boolean) { writer.value((boolean) value); } else if (value instanceof Number) { writer.value((Number) value); } else { writer.value(value.toString()); } } catch (IOException e) { throw new AssertionError(e); } }); } writer.endObject(); } catch (IOException e) { throw new AssertionError(e); } out.append(System.lineSeparator()); return out.toString(); }  }
JsonFormatter extends Formatter { @Override public String format(LogRecord record) { Instant timestamp = Instant.ofEpochMilli(record.getMillis()); StringWriter out = new StringWriter(); try (JsonWriter writer = new JsonWriter(out)) { writer.setSerializeNulls(false); writer.setHtmlSafe(false); writer.beginObject(); writer.name("timestamp") .beginObject() .name("seconds").value(timestamp.getEpochSecond()) .name("nanos").value(timestamp.getNano()) .endObject(); writer.name("severity").value(severity(record.getLevel())); writer.name("thread").value(Thread.currentThread().getName()); writer.name("message").value(formatMessage(record)); LogContext logContext = LogContext.current(); if (logContext != null) { logContext.forEach((name, value) -> { try { writer.name(name); if (value == null) { writer.nullValue(); } else if (value instanceof Boolean) { writer.value((boolean) value); } else if (value instanceof Number) { writer.value((Number) value); } else { writer.value(value.toString()); } } catch (IOException e) { throw new AssertionError(e); } }); } writer.endObject(); } catch (IOException e) { throw new AssertionError(e); } out.append(System.lineSeparator()); return out.toString(); }  @Override String format(LogRecord record); @Override synchronized String formatMessage(LogRecord record); }
JsonFormatter extends Formatter { @Override public String format(LogRecord record) { Instant timestamp = Instant.ofEpochMilli(record.getMillis()); StringWriter out = new StringWriter(); try (JsonWriter writer = new JsonWriter(out)) { writer.setSerializeNulls(false); writer.setHtmlSafe(false); writer.beginObject(); writer.name("timestamp") .beginObject() .name("seconds").value(timestamp.getEpochSecond()) .name("nanos").value(timestamp.getNano()) .endObject(); writer.name("severity").value(severity(record.getLevel())); writer.name("thread").value(Thread.currentThread().getName()); writer.name("message").value(formatMessage(record)); LogContext logContext = LogContext.current(); if (logContext != null) { logContext.forEach((name, value) -> { try { writer.name(name); if (value == null) { writer.nullValue(); } else if (value instanceof Boolean) { writer.value((boolean) value); } else if (value instanceof Number) { writer.value((Number) value); } else { writer.value(value.toString()); } } catch (IOException e) { throw new AssertionError(e); } }); } writer.endObject(); } catch (IOException e) { throw new AssertionError(e); } out.append(System.lineSeparator()); return out.toString(); }  @Override String format(LogRecord record); @Override synchronized String formatMessage(LogRecord record);  }