@Override
  public byte[] encode(ILoggingEvent event) {
    var baos = new ByteArrayOutputStream();
    try (var generator = jsonFactory.createGenerator(baos)) {
      generator.writeStartObject();

      // https://cloud.google.com/logging/docs/structured-logging#structured_logging_special_fields
      // https://github.com/googleapis/java-logging-logback/blob/main/src/main/java/com/google/cloud/logging/logback/LoggingAppender.java

      writeTimestamp(generator, event);
      writeSeverity(generator, event);
      writeLogger(generator, event);
      writeMessage(generator, event);
      writeThread(generator, event);

      writeServiceContext(generator);
      writeTraceContext(generator);

      var mdc = event.getMDCPropertyMap();
      writeMdc(generator, mdc);

      writeKeyValue(generator, event);

      if ("ERROR".equals(event.getLevel().toString())) {
        writeError(generator, event, mdc);
      }
      writeStackTrace(generator, event);

      generator.writeEndObject();
      generator.writeRaw('\n');
      generator.flush();
    } catch (NullPointerException | IOException e) {
      return logFallbackError(event, e);
    }
    return baos.toByteArray();
  }
@Test
  void encode_kv() {

    var e = mockEvent();
    when(e.getLevel()).thenReturn(Level.DEBUG);
    when(e.getFormattedMessage()).thenReturn("oha, sup?");

    when(e.getKeyValuePairs())
        .thenReturn(
            List.of(
                new KeyValuePair("req", Map.of("url", "https://example.com", "method", "GET")),
                new KeyValuePair("a", Map.of("b", Map.of("c", "d"))),
                new KeyValuePair("status", 500)));

    var msg = encoder.encode(e);

    assertMatchesJson(
        """
                      {"a":{"b":{"c":"d"}},"logger":"com.example.MyLogger","message":"oha, sup?","req":{"method":"GET","url":"https://example.com"},"severity":"DEBUG","status":"500","thread_name":"main","time":"2024-08-09T14:13:33Z"}
                      """,
        msg);
  }