v2.1Руководство
Потоки и большие файлы
Как читать логи любого размера с постоянным расходом памяти и обратным давлением.
Метод parser.stream(readable) принимает любой Readable и возвращает асинхронный итератор записей. Строки собираются из кусков, пришедших из потока, так что граница чанка в середине строки ничего не ломает.
import { createReadStream } from 'node:fs';
for await (const rec of parser.stream(createReadStream('big.log'))) {
// rec уже разобран
}Обратное давление#
Пока вы обрабатываете запись внутри for await, чтение источника приостановлено. Не нужно вручную вызывать pause() и resume(). Если обработка медленная, например запись в базу, буфер не растёт.
Сжатые файлы и stdin#
Сверло не распаковывает данные само. Поставьте декомпрессор в цепочку:
import { createGunzip } from 'node:zlib';
const src = createReadStream('access.log.gz').pipe(createGunzip());
for await (const rec of parser.stream(src)) { /* ... */ }Для стандартного ввода передайте process.stdin.
Как работает буфер#
| Параметр | По умолчанию | Назначение |
|---|---|---|
maxLineLength | 65536 | Строка длиннее лимита не копится в памяти: она отбрасывается с ошибкой E_LINE_TOO_LONG |
highWaterMark | 65536 | Размер чанка чтения |
encoding | utf8 | Кодировка входа; битые последовательности заменяются на U+FFFD |
Остановка#
break внутри цикла закрывает источник. Если нужно остановить чтение по таймеру, передайте signal:
const ctl = new AbortController();
setTimeout(() => ctl.abort(), 5000);
for await (const rec of parser.stream(src, { signal: ctl.signal })) { /* ... */ }При отмене итератор завершается без исключения, а parser.stats.aborted становится true.
Реальные объёмы
Лимиты и значения по умолчанию в этом разделе — часть вымышленного API. Принципы (потоковое чтение, лимит длины строки, обратное давление) общие для любого разборщика логов.