Доброго дня. Это мой первый пост на хабре, поэтому не будьте особо строги к нему.

В мире разработки, системного администрирования и DevOps не смотря на то, что давно существуют и заняли свою нишу инструменты, связанные с централизованным сбором, визуализацией и анализом логов (graylog, ELK/EFK, loki, loggly и другие), всё ещё существует необходимость периодически взять шашку в руки и поработать со старыми/добрыми (а может быть и не очень добрыми) текстовыми логами. За 21 год своей деятельности я успел побыть системным администратором, DevOps инженером, разработчиком, CTO и системным аналитиком, но необходимость периодической работы с логами неизменно присутствовала в том или ином виде всегда. Это может быть разбор вывода нового сервиса или контейнера на машине разработчика, что-то, что ещё не успели завести (или сознательно по каким-либо причинам не завели) на централизованную систему сбора логов или, например, сервис, временно включенный в режиме debug для поиска причин проблемы. Ситуаций бывает много и ситуации бывают разные, а текстовые логи были, есть и ещё долго будут с нами.

Все, кто как-либо связан с DevOps знают про такие утилиты как more, less, tail, head, grep, sed, awk (а кто-то и ещё десяток более специфичных) и при необходимости их используют, но из тех, с кем я общался, никто не подтвердил мне, что знает про lnav. Я и сам не знал и искал нечто подобное более десяти лет. lnav — это не просто швейцарский армейский нож в мире работы с логами, а целый космический корабль, на котором можно улететь в соседнюю галактику. Мой мир разделился на "до" и "после" знакомства с этой утилитой. Там, где раньше требовались часы, а то и десятки часов на анализ логов, теперь хватает считанных минут.

Кратко об основных возможностях lnav.

  1. Позитивные и негативные фильтры: lnav предоставляет возможность включать и отключать (в том числе временно) фильтры, позволяя вам сосредоточиться только на нужной информации. Позитивные фильтры находят соответствующие записи, а негативные исключают ненужные, причём тут же можно видеть, сколько строк попало под фильтр и отображается в текущий момент. Естественно, поддерживаются регулярные выражения. Т.е. можно например, быстро найти все залогированные запросы в БД, время выполнения которых превышало определённое количество секунд .

  2. Удобная навигация: Утилита предлагает интуитивно понятный интерфейс с возможностью навигации в стиле VIM. Работают HJKL, переход в начало и конец по gg и G и некоторые другие возможности. Можно легко перемещаться к следующей (e) или предыдущей (E) ошибке, либо к тому, что lnav считает ошибкой и т.д.. Возможность быстрого перехода к нужным блокам информации значительно ускоряет процесс работы.

  3. Подсветка синтаксиса и темизация: Подсветка синтаксиса делает логи более читаемыми, а возможность настроить тему позволяет адаптировать интерфейс под ваши предпочтения. Это особенно важно при работе с большими файлами, где детали могут легко ускользнуть из-за ненадлежащего оформления. Кто пытался отгрепать лог в несколько миллионов SQL запросов - поймёт и оценит. Также lnav умеет делать prettify (да, я всё ещё не знаю, как этот термин правильно перевести на русский) для xml и json.

  4. График статистики: lnav позволяет выводить график статистики поступления записей в лог на единицу времени. Длина заполненной строки графика показывает количество строк за единицу времени относительно соседних строк и может иметь до трёх участков разного цвета: серый для нормальных записей, жёлтый для warning записей и красный для error записей. Это позволяет быстро визуализировать состояние системы и понять, когда в вашей системе что-то пошло не так. Т.е. вы сразу увидите, в какой точке резко выросло количество записей с ошибками, даже если их абсолютное количество составляет менее сотни на несколько десятков/сотен тысяч нормальных записей.

  5. Определение логлевела: Утилита позволяет явно указывать логлевел для отображения, что помогает сосредоточиться на наиболее критичных записях и не отвлекаться на менее значимые.

  6. Множественные форматы логов: lnav поддерживает одновременное отображение сразу нескольких файлов логов различного формата (да-да, с индивидуальной для каждого формата подсветкой синтаксиса), что упрощает процесс анализа информации из различных источников и ведет к более полному пониманию происходящего.

  7. Внутренний SQL и разбиение по полям: Интересное и, возможно, спорное решение, но lnav переводит весь лог в SQLite базу, которую хранит в оперативной памяти. Это позволяет вам использовать различные части записи в логе как отдельные поля и делать sql запросы к данным ваших логов.

    SELECT c_ip, count(*), sum(sc_bytes) AS total FROM access_log GROUP BY c_ip ORDER BY total DESC;

  8. Работа с залогированными SQL запросами: При фильтрации lnav анализирует запросы SQL и выводит все строки, которые соответствуют фильтру, даже если запрос состоит из нескольких строк. Это бесценная возможность. Т.е. введя в фильтр что-то вроде "uid=123" вы получите полные записи и с однострочными запросами и с теми, где это встретилось на 105-й строке запроса. Естественно, место вхождения будет подсвечено.

  9. Объединение записей по времени: Даже если форматы времени в логах различны, lnav попытается их интерпретировать и отобразит записи на единой временной шкале. Это позволяет видеть чередование строк из различных файлов по мере их поступления, что улучшает общую картину происходящего и позволяет обнаруживать взаимосвязи между событиями.

  10. Экспорт данных: После применения всех необходимых фильтров у вас есть возможность выделить блок строк, в том числе включающий данные из разных файлов и экспортировать эти данные в новый файл в формате текста, JSON или CSV. Это существенно упрощает подготовку отчетов и дальнейший анализ. В том числе вы можете выделить нужные для экспорта данные не одним блоком, а несколькими.

  11. Создание собственных форматов лога: Вы можете использовать специальный синтаксис, чтобы описать свой формат лога для разделения его по полям. Это даёт возможность более продуктивного анализа в будущем, поскольку вы сможете настроить lnav под специфические требования вашего конкретного проекта. Причём можно как создать формат с нуля, так и наследовать поля какого-то уже описанного формата.

  12. Закладки и дополнительные возможности: lnav позволяет создавать закладки, что помогает быстро возвращаться к нужным участкам данных по аналогии с тем, как это работает в vim.

  13. Возможность неинтерактивной работы с lnav и создания скриптов для обработки данных: Одной из мощных возможностей lnav является возможность неинтерактивной работы, что позволяет вам писать собственные скрипты для автоматизации анализа логов и обработки данных. Это особенно полезно в тех случаях, когда требуется обрабатывать большие объемы информации или выполнять регулярные задачи.

    $ lnav -n \ -c ';SELECT c_ip, count(*) AS total FROM access_log GROUP BY c_ip ORDER BY total DESC LIMIT 10' \ -c ':write-csv-to -' \ access.log c_ip,total 10.208.110.176,2989570 10.178.4.102,11183 10.32.110.197,2020 10.29.165.250,443

  14. Сохранение и загрузка сессий: в lnav можно сохранять сессии. Это позволяет сохранить текущее состояние просмотра логов, включая примененные фильтры, аннотации и все выполненные действия.

    Сохранение сессии: :save-session имя_сессии.lnav

    Загрузка ранее сохранённой сессии: :load-session имя_сессии.lnav

  15. Работа с пайпами: Если необходимо, то можно пользоваться пайпами, например: tail -n 1000 -f somefile.log | lnav.

Больше информации можно получить в официальной документации.

Ложки дёгтя

Не бывает инструментов, состоящих из одних достоинств, поэтому ниже о выявленных мною недостатках:

  • Так как лог полностью загружается в оперативную память, то мы ограничены объёмом этой памяти. Если у вас в текущий момент недостаток свободной оперативной памяти, то вероятно, будет плохой идеей открывать на боевом сервере в lnav несколько десятков логов по гигабайту каждый. При работе с большим количеством логов следите за оперативной памятью или выгружайте логи на локальную машину.

  • Из-за того, что содержимое лога полностью переводится в SQLite, открытие больших объёмов логов может занимать существенное время на системах со слабым CPU.

  • Более высокий порог входа. "Он вам не grep", одних знаний regex тут будет явно недостаточно, если вы собираетесь использовать lnav на полную катушку.

  • Иногда по необъяснимым причинам особенно на больших объёмах данных lnav может упасть. К сожалению, такое периодически происходит.

Заключение

На мой взгляд преимущества lnav явно превышают недостатки. lnav это мощный и универсальный инструмент, который значительно упрощает процесс анализа логов. Совокупность его возможностей делает его незаменимым помощником для всех, кому приходится иметь дело с логами. За те годы, что я использую lnav, он стал обязательным инструментом на каждом моем хосте — как домашнем, так и рабочем. Усилия, затраченные на изучение lnav окупились стократно. Если вы не слышали об этом инструменте, настоятельно рекомендую вам с ним ознакомиться.

Вы можете узнать больше о lnav на официальном сайте.

Комментарии (20)


  1. ajijiadduh
    31.08.2024 06:57

    такие утилиты как awk

    это не утилита, а язык программирования


    1. MasterShu Автор
      31.08.2024 06:57
      +6

      Да, разработчики заявляют именно так и понятно, почему. На их месте я бы поступал также. Но де-факто применение awk преимущественно утилитарное. Нигде не видел, чтобы его использовали именно как интерпретатор ЯП в полном смысле этого слова. Скорее как аналог excel для cli.


  1. Spellinger
    31.08.2024 06:57

    а чем лучше елки?


    1. dyadyaSerezha
      31.08.2024 06:57
      +3

      Тем, что ёлку надо: 1) иметь, 2) получить разрешение на залив в неё твоих логов с дев или тестового стенда, точнее, два разрешения - от группы ёлки и от админов сети для физического доступа, 3) настроить. 4) часто логи в центральном хранилище любого типа запаздывают на минуты, а надо здесь и сейчас, немедленно. Но без перевода в БД, конечно, если в идеале.


    1. MasterShu Автор
      31.08.2024 06:57
      +5

      Тем, что решили вы переключить сервис в дебаг, а дебага там столько и он настолько ситуативный, что жалко этим нагружать ELK. Другой сценарий - контейнер, бегущий локально на машине разработчика. Для него поднимать елк или аналог - бессмысленно, как и подключать его локальный контур к центральному елк, а пару - тройку гигабайт дебаг лога проанализировать надо. Либо, как третий вариант - это может быть вообще пет проект.


  1. vitaly_il1
    31.08.2024 06:57
    +1

    Согласен, для своей ниши интересный инструмент, как и goaccess.
    (хотя и немного прошлый век - ну, я и сам такой)


    1. gedev
      31.08.2024 06:57

      Я пытался использовать goaccess для казалось бы банальной задачи — анализ логов nginx на почти ничем не занятой машине (логов кот наплакал). Честно говоря, гораздо практичней оказались grep, awk и less. goaccess по факту даёт только очень поверхностную картинку происходящего. Как только надо изучить частности — он всё. Но это мой опыт. Было бы интересно послушать как применить goaccess с реальной пользой. Я тут имею в виду, например, хотя бы отчёты о том, сколько за последнее время было 5XX кодов, на какие URL и от кого были эти запросы.


      1. vitaly_il1
        31.08.2024 06:57

        Я обычно и стараюсь не влезать сильно в подробности.
        "Почему сервер медленный/перегружен?" - заглядываю в лог через goaccess и отвечаю - кол-во запросов выросло в пять раз, из них 70% - с таких-то адресов.
        Часто этого хватает. Но разумеется, нет универсальных инструментов.


  1. MasterShu Автор
    31.08.2024 06:57
    +2

    За наводку на goaccess - спасибо, изучу. Я вообще очень люблю tui ещё со времён расцвета fido и bbs. :)


    1. dryja
      31.08.2024 06:57

      Да опять это ваше наше Фидо на хабре в комментах уже который день)


  1. savostin
    31.08.2024 06:57

    lnav переводит весь лог в SQLite базу, которую хранит в оперативной памяти

    Хм, а зачем хранить SQLite в памяти? Он с диска работает не намного медленнее. Кстати, с чего Вы взяли, что в памяти? В документации не нашел такого, а наоборот, написано, что используется vtable.


    1. MasterShu Автор
      31.08.2024 06:57

      Я просто наблюдал в момент подгрузки логов за тем, как уменьшалась оперативная память и размеры сравнимы. Других объяснений у меня нет. Насчёт "с диска не намного медленнее" - не проверял, утверждать не буду, но есть сомнения, что выборка из sqlite базы с таблицей в 20гб, скажем, пусть даже с ssd или sas диска займёт сравнимое время, что и из оперативной памяти.


      1. batyrmastyr
        31.08.2024 06:57

        Как насчёт (1) кеширования файла в ОЗУ силами ОС (2) mmap?


        1. MasterShu Автор
          31.08.2024 06:57

          Файла самого лога? Возможно, но скорее tmpfs, если файл продолжает дописываться в процессе анализа.


      1. nEkToSAN
        31.08.2024 06:57

        У меня по работе встречались машинки, у которых за день логов набиралось под 120-140 GB (например, Fortigate NGFW, на котором есть куча фв политик и несколько сервисов поднято), если всё это попытаться подгрузить в ОЗУ... А ведь иногда ещё надо и логи за последние 7-10 дней просмотреть. Надеюсь, на самом там не ОЗУ хранит данные.


        1. MasterShu Автор
          31.08.2024 06:57

          Для этого можно вырезать нужный кусок пайпом с помощью других утилит и перенаправить выход на lnav.


  1. Pumboss
    31.08.2024 06:57
    +1

    Удобная навигация и навигация в стиле Vim - это абсолютно разные штуки. Но ради хорошего инструмента можно и потерпеть.


    1. MasterShu Автор
      31.08.2024 06:57
      +1

      Я больше 15 лет пользуюсь vim'ом и это накладывает свой отпечаток. Можно считать, что это что-то вроде профдеформации и это удобно для меня и других пользователей вим. Впрочем, навигация с помощью обычных курсорных клавиш и pgup/pgdwn/home/end тоже работает, так что поддержка вим хоткеев скорее опция или бонус.


  1. Kenya-West
    31.08.2024 06:57

    lnav очень узколоб и ограничен, когда видит JSON-логи (где каждая запись/строка — это JSON-объект). Для каждого, даже очень популярного решения, нужно писать свой формат. А что, если схема у JSON поменяется? Снова формат писать? Самостоятельно он парсить JSON почему-то не умеет и никаких попыток не предпринимает вообще. Мой issue это подтверждает.

    Поэтому jl всему голова.


    1. MasterShu Автор
      31.08.2024 06:57

      Всё так. С jl не сталкивался, но посмотрю, спасибо!