Automatic JSON extraction from strings

We automatically recognize when a field contains a generic string followed by a JSON, and we expand it so that you can search it easily.

Example of payloads Logs supports:

Simple text string
{"message": "Hello, Logs!"}

// ... will be parsed into this
{
  "message": "Hello, Logs!"
}
Simple JSON
{"message": "{\"text\": \"Hello, Logs!\", \"number\": 100}"}

// ... will be parsed into this
{
  "message.text": "Hello, Logs!",
  "message.number": 100
}

If there is any string before the JSON, the string will be in the original field and the parsed fields will be added with _json suffix, e.g. message and message_json:

String followed by JSON
{"message": "Nov 30 11:22:34 localdomain sudo[14170]: {\"metadata\":{\"server_name\":\"Optimus\",\"local_time_zone\":\"GMT+1\",\"created_at\":1631689974}}"

// ... will be parsed into this
{
  "message": "Nov 30 11:22:34 localdomain sudo[14170]: ",
  "message_json.metadata.server_name": "Optimus",
  "message_json.metadata.local_time_zone": "GMT+1",
  "message_json.metadata.created_at": 1631689974
}

All fields ending with a valid JSON are parsed in this way:

Multiple JSONs
{
  "level": "INFO",
  "data": {
    "request": "Started GET /api/v1/heartbeat/sUTvXxY2c6yaA91RcAkxA8c5 {\"context\":{\"thread_id\":1234,\"pid\":123},\"level\":\"INFO\"}",
    "response": "204 No Content {\"context\":{\"thread_id\":1234,\"pid\":456},\"duration\":35.63}"
  }
}

// ... will be parsed into this
{
  "level": "INFO",
  "request": "Started GET api/v1/heartbeat/sUTvXxY2c6yaA91RcAkxA8c5",
  "request_json.context.thread_id": 1234,
  "request_json.context.pid": 123,
  "request_json.level": "INFO",
  "response": "204 No Content",
  "response_json.context.thread_id": 1234,
  "response_json.context.pid": 456,
  "response_json.duration": 35.63
}