JSON Lines: формат, который не надо читать целиком
Файл, где на каждой строке лежит отдельный JSON-объект, а не один большой массив. Выглядит как недоразумение, пока не столкнёшься с выгрузкой на десять гигабайт.
В чём разница
Обычный JSON — единое целое. Чтобы получить первый элемент массива, формально нужно убедиться, что документ корректен до последней скобки. Отсюда следствие: файл разбирается целиком, и память расходуется пропорционально размеру.
JSON Lines устроен иначе: каждая строка — самостоятельный документ. Читать можно по одной строке, начинать с середины, обрывать в любом месте. Файл на десять гигабайт обрабатывается при потреблении памяти в несколько мегабайт.
Расширения — .jsonl, .ndjson, иногда просто .json или .log. Определять формат по расширению бессмысленно: надёжнее посмотреть, являются ли первые строки самостоятельными объектами.
Где он встречается
- Логи. Строку можно дописать в конец файла без перечитывания — для журнала это решающее свойство.
- Выгрузки из API постранично. Ответы страниц просто склеиваются, и результат остаётся корректным.
- Обмен между системами обработки данных. BigQuery, ClickHouse и подобные читают JSON Lines напрямую.
- Наборы данных для машинного обучения. Стандарт де-факто.
Чем открыть
Текстовый редактор покажет содержимое, но без колонок и фильтров — на сотне тысяч строк толку немного. Excel не поймёт формат вовсе. Python и jq подойдут, если есть кому писать код.
Если задача — посмотреть, найти нужные записи и выгрузить подмножество, достаточно просмотрщика, который понимает формат: строки становятся таблицей, ключи — колонками, вложенность разворачивается через точку.
Важная деталь: в реальном файле встречаются битые строки — оборвалась запись, попал служебный вывод. Разбор не должен на этом падать. Правильное поведение — пропустить такие строки и сказать, сколько их оказалось.
Как превратить логи в что-то осмысленное
Типовой сценарий с журналом приложения:
- открыть файл — каждая запись станет строкой, поля
ts,level,msg— колонками; - отфильтровать уровень:
level = 'error'; - сгруппировать по коду или сообщению с количеством — сразу видно, что повторяется чаще всего;
- посмотреть распределение по времени и выгрузить выборку тому, кто будет разбираться.
Всё это без командной строки и без загрузки журнала — который вполне может содержать чувствительные данные — на чужой сервер.
Частые вопросы
Нужно ли переименовывать файл в .jsonl?
Нет, формат определяется по содержимому: если первые строки — самостоятельные объекты, файл читается как JSON Lines.
Что будет с битыми строками?
Они пропускаются, а их количество выводится предупреждением — молча терять данные неправильно.
Можно ли преобразовать обычный JSON в JSON Lines?
Да, выгрузка в JSON Lines есть: удобно, когда нужно отдать большой массив системе, читающей построчно.