Все команды фильтрации вводятся через двоеточие (:).

---

1. Основные команды фильтрации

  • Скрыть строки по шаблону (Исключение):
:filter-out REGEX

*Пример:* Исключить все логи уровня DEBUG:

:filter-out DEBUG
  • Показать ТОЛЬКО строки по шаблону (Включение):
:filter-in REGEX

*Пример:* Оставить только ошибки и предупреждения:

:filter-in ERROR|WARN
  • Очистить все созданные фильтры:
:clear-filters

---

2. Фильтрация по уровню логирования (Log Level)

lnav автоматически распознаёт уровень логов (INFO, WARN, ERROR, DEBUG, FATAL). Вы можете быстро переключать минимальный отображаемый уровень с помощью горячих клавиш:

  • i / Shift + i — понизить / повысить минимальный уровень отображаемых сообщений.
  • d — быстро скрыть / показать сообщения уровня DEBUG.

---

3. Фильтрация по времени

Для удобной работы с временными отрезками используйте команду :goto или специализированные команды фильтрации по времени:

  • Перейти к конкретной дате/времени:
:goto 2026-10-26 10:00:00

*(Также можно использовать относительные указания, например: :goto 15m ago)*

  • Задать временной диапазон:
:filter-between 2026-10-26 09:00:00 AND 2026-10-26 10:00:00
  • Отобразить сообщения ПОСЛЕ определенного времени:
:hide-unmatching-lines-before 2026-10-26 09:00:00

---

4. Управление активными фильтрами

Чтобы посмотреть, какие фильтры сейчас применены, и управлять ими интерактивно:

1. Нажмите TAB — переключит нижнюю панель в режим просмотра фильтров (Filter View).
2. Используйте стрелки для выбора фильтра:

  • Пробел — временно включить / отключить выбранный фильтр.
  • D или Delete — удалить выбранный фильтр.

3. Нажмите TAB снова, чтобы вернуться к основному окну логов.

---

5. Полезный совет: Быстрый поиск vs Фильтрация

  • Если вам нужно просто подсветить и перемещаться по найденным совпадениям, используйте обычный поиск через /:
/connection refused
  • Нажмите n для перехода к следующему совпадению, N — к предыдущему.
  • Если нужно полностью скрыть лишний шум из экрана — используйте :filter-in или :filter-out.

*****

Фильтрация в lnav действует на весь открытый массив логов — на все загруженные файлы, их строки и весь временной диапазон (как прошлые записи, так и новые, поступающие в реальном времени).

Ключевые особенности работы фильтров:

1. Глобальный охват (все файлы сразу):
Если у вас открыто несколько файлов (например, lnav /var/log/nginx/*.log), фильтр :filter-in или :filter-out применяется одновременно к общему агрегированному потоку.
2. Работа в режиме tail -f (динамический поток):
Фильтры активны постоянно. Если в отслеживаемый файл дописываются новые строки, они проходят через текущие правила фильтрации «на лету» перед выводом на экран.
3. Фильтрация не удаляет данные:
Команды :filter-in / :filter-out лишь меняют отображение на экране (view-level filtering). Все оригинальные строки остаются в памяти lnav. Как только вы удалите или отключите фильтр (:clear-filters или через панель по TAB), скрытые строки снова станут visible без необходимости перезагружать файлы.
4. Комбинация с временными ограничениями:
Если задать ограничения по времени (например, :filter-between или :hide-unmatching-lines-before), временной диапазон работает как дополнительный слой фильтрации — отображаются только те строки, которые проходят и по регулярным выражениям, и попадают в указанные временные рамки.

*******

1. Сложные PCRE-фильтры (:filter-in / :filter-out)

lnav использует полноценный синтаксис PCRE (Perl-Compatible Regular Expressions) с поддержкой негативных/позитивных проверок (lookaround), именованных групп и атомарных группировок.

Фильтрация с условиями И / ИЛИ / НЕ

  • ИЛИ (Match A or B): Оставить только ошибки 5xx или таймауты:
:filter-in HTTP/1\.[01]"\s+5\d\d|connection timed out
  • НЕ (Negative Lookahead): Показать все ошибки 500, кроме вызываемых ресурсом /healthcheck:
:filter-in 500 (?!.*?\b/healthcheck\b)
  • Строгий парсинг IP-адресов и диапазонов: Исключить локальный трафик (127.0.0.1, 10.x.x.x, 192.168.x.x):
:filter-out \b(127\.0\.0\.1|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})\b
  • Исключение шума без потери полезных строк: Показать все строки с ERROR или CRITICAL, но скрыть стектрейсы Java/Python, начинающиеся с пробелов или at ...:
:filter-out ^\s+at\s+|^Traceback|^\s*File "

---

2. Выполнение SQL-запросов к логам

lnav автоматически парсит структурированные логи (syslog, nginx, apache, systemd, json) и монтирует их во встроенную SQLite-БД как виртуальную таблицу logline (или специализированные таблицы вида access_log, syslog_log).

Для входа в режим SQL нажмите ; (точка с запятой).

Посмотреть структуру таблицы:

;PRAGMA table_info(logline);

Агрегация HTTP-запросов по кодам ответов и среднему времени ответа (Nginx/Apache)

;SELECT sc_status AS status_code, count(*) AS total_requests, round(avg(request_time), 3) AS avg_time_sec FROM access_log GROUP BY sc_status ORDER BY total_requests DESC;

Поиск Top-10 IP-адресов, генерирующих 404 ошибки

;SELECT c_ip, count(*) AS errors_count FROM access_log WHERE sc_status = 404 GROUP BY c_ip ORDER BY errors_count DESC LIMIT 10;

Подсчет ошибок по 5-минутным интервалам

Использование встроенной функции date_time_to_bucket_num:

;SELECT date_time_to_bucket_num(log_time, '5m') AS bucket, count(*) AS err_count FROM logline WHERE log_level IN ('error', 'critical') GROUP BY bucket ORDER BY bucket ASC;

Поиск медленных запросов по именованным полям JSON-логов

Если открыт файл .jsonl или .log в формате JSON, lnav автоматически разбирает ключи в столбцы таблицы:

;SELECT log_time, log_body, jget(log_raw, '/duration_ms') AS duration FROM logline WHERE cast(jget(log_raw, '/duration_ms') as integer) > 1000;

---

3. Экспорт результатов SQL-запроса

Результаты выполения SQL-запроса выводятся в отдельном текстовом view. Из него данные можно легко сохранить в CSV/JSON:

  • Сохранить результат в CSV:
:write-csv-to /tmp/report.csv
  • Сохранить результат в JSON:
:write-json-to /tmp/report.json

*****

Пользовательские форматы в lnav описываются с помощью JSON-файлов конфигурации. lnav автоматически загружает все .json файлы из каталога конфигураций:

  • Пользовательский каталог: ~/.config/lnav/formats/installed/ (или ~/.lnav/formats/installed/)
  • Системный каталог: /etc/lnav/formats/

---

1. Минимальная структура JSON-конфига

Создайте файл, например ~/.config/lnav/formats/installed/my_custom_app.json:

{
  "$schema": "https://lnav.org/schemas/format-v1.json",
  "my_custom_app_log": {
    "title": "My Custom Application Log",
    "description": "Format for parsing my custom service logs",
    "url": "https://example.com/docs",
    "regex": {
      "std": {
        "pattern": "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d+Z) \\[(?<level>\\w+)\\] \\[(?<service>\\w+)\\] (?<body>.*)$"
      }
    },
    "value": {
      "timestamp": {
        "kind": "string",
        "identifier": true
      },
      "level": {
        "kind": "string",
        "identifier": true
      },
      "service": {
        "kind": "string",
        "identifier": true
      },
      "body": {
        "kind": "string"
      }
    },
    "sample": [
      {
        "line": "2026-10-26T10:15:30.123Z [ERROR] [auth-service] User authentication failed for uid=1002"
      }
    ]
  }
}

---

2. Ключевые секции формата

regex (Регулярные выражения для парсинга)

Содержит регулярное выражение PCRE с именованными группами (?<name>...).

  • Обязательно должны быть группы timestamp и body (или level).
  • Можно объявлять несколько паттернов (например, std, extended), если в файле встречаются разные типы строк. lnav пробует их по очереди.

value (Типы данных и типы полей)

Описывает поля, извлеченные из regex. Каждое поле автоматически становится столбцом в SQLite-таблице:

  • "kind": тип значения (string, integer, float, boolean, date).
  • "identifier": true: помечает поле как категориальный идентификатор (позволяет lnav подсвечивать значение индивидуальным цветом).
  • "hidden": true: скрыть поле из текстового интерфейса, но оставить доступным для SQL-запросов.

sample (Примеры для валидации)

Массив тестовых строк лога. Важно: при запуске lnav валидирует ваши regex по указанным sample. Если регулярное выражение не сможет распарсить хотя бы один sample, формат не загрузится, а lnav выведет ошибку со сдвигом символов.

---

3. Специальные опции для продвинутой конфигурации

  • Уровни логирования (level):

Если имена уровней отличаются от стандартных, их можно спроецировать на встроенные типы lnav:

"level": {
  "error": "ERR|CRITICAL|FATAL",
  "warning": "WARN|WARNING",
  "info": "INFO|NOTICE"
}
  • Парсинг JSON-логов (JSON lines / structured logs):

Если лог уже пишется в JSON, регулярка не нужна. Используется блок json-fields:

{
  "my_json_log": {
    "title": "Structured JSON log",
    "json-fields": {
      "timestamp": "time",
      "level": "level",
      "body": "message"
    },
    "sample": [
      { "line": "{\"time\": \"2026-10-26T10:00:00Z\", \"level\": \"info\", \"message\": \"Server started\"}" }
    ]
  }
}
  • Подсветка синтаксиса (Highlighters):

Можно добавить кастомные правила подсвечивания ключевых слов цветом:

"highlights": {
  "user_ids": {
    "pattern": "uid=\\d+",
    "color": "#ff5555"
  }
}

---

4. Проверка и отладка формата

1. Тестирование файла конфигурации:
Запустите lnav с флагом проверки:

lnav -C

Если в синтаксисе JSON или PCRE есть ошибка, lnav укажет конкретную строку и несовпадение с sample.
2. Проверка работы на реальном файле:
Откройте лог и нажмите CTRL + W — lnav переключит вывод в режим Log Format Viewer, где покажет, какой именно формат применился к текущей строке и как распределились захваченные поля.

*****

Для обработки многострочных логов (например, когда за базовой записью следует стектрейс Java, Python или C++) в lnav используется директива multiline. Она указывает парсеру, считается ли новая строка продолжением предыдущей записи или началом новой.

---

JSON-конфигурация многострочного формата

Создайте файл ~/.config/lnav/formats/installed/multiline_app.json:

{
  "$schema": "https://lnav.org/schemas/format-v1.json",
  "multiline_app_log": {
    "title": "Application Log with Stack Traces",
    "description": "Format handling multi-line stack traces and errors",
    "regex": {
      "std": {
        "pattern": "^(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) \\[(?<level>DEBUG|INFO|WARN|WARNING|ERROR|CRITICAL)\\] \\[(?<thread>[^\\]]+)\\] (?<body>.*)$"
      }
    },
    "multiline": true,
    "line-mode": "raw",
    "level": {
      "error": "ERROR|CRITICAL",
      "warning": "WARN|WARNING",
      "info": "INFO",
      "debug": "DEBUG"
    },
    "value": {
      "timestamp": {
        "kind": "string"
      },
      "level": {
        "kind": "string",
        "identifier": true
      },
      "thread": {
        "kind": "string",
        "identifier": true
      },
      "body": {
        "kind": "string"
      }
    },
    "sample": [
      {
        "line": "2026-10-26 10:15:30.123 [ERROR] [main] Database connection failed\njava.sql.SQLException: Access denied for user 'root'@'localhost'\n\tat com.example.db.Connector.connect(Connector.java:42)\n\tat com.example.App.main(App.java:15)"
      },
      {
        "line": "2026-10-26 10:15:31.000 [INFO] [main] Retrying connection in 5 seconds..."
      }
    ]
  }
}

---

Как это работает:

1. "multiline": true
Сообщает lnav, что записи могут занимать несколько строк. Если следующая строка файла не соответствует основному regex (например, у неё нет таймштампа в начале), lnav автоматически присоединяет её к полю body предыдущей логической записи.
2. Относительный порядок в sample
В секции sample многострочный пример передается единым строковым значением с переносами \n. Обязательно добавьте хотя бы один многострочный пример и один однострочный, чтобы lnav корректно отвалидировал регулярное выражение.
3. Опционально: "multiline": false с предсказанием продолжения
Если вам нужно явно задать регулярное выражение для строк-продолжений (например, когда многострочный фрагмент имеет специальный префикс вроде => или пробелы), можно использовать параметр body-regex или паттерн для продолжений в блоке regex. Однако в 95% случаев достаточно установить "multiline": true.

---

Валидация и проверкa

1. Проверьте синтаксис конфига:

lnav -C

2. Откройте лог-файл со стектрейсами и нажмите c (команда :toggle-view). В многострочном режиме lnav подсветит всю запись (включая весь стектрейс) как единый лог-блок, к которому применимы единые правила фильтрации.