Советы и рекомендации по преобразованию неструктурированных данных из логов в ELK Stack используя GROK в LogStash

    Структурирование неструктурированных данных с помощью GROK


    Если вы используете стек Elastic (ELK) и заинтересованы в сопоставлении пользовательских журналов Logstash с Elasticsearch, то этот пост для вас.



    Стек ELK – это аббревиатура для трех проектов с открытым исходным кодом: Elasticsearch, Logstash и Kibana. Вместе они образуют платформу управления журналами.


    • Elasticsearch – это поисковая и аналитическая система.
    • Logstash – это серверный конвейер обработки данных, который принимает данные из нескольких источников одновременно, преобразует их и затем отправляет в “тайник”, например Elasticsearch.
    • Kibana позволяет пользователям визуализировать данные с помощью диаграмм и графиков в Elasticsearch.

    Beats появился позже и является легким грузоотправителем данных. Введение Beats преобразовало Elk Stack в Elastic Stack, но это не главное.


    Эта статья посвящена Grok, которая является функцией в Logstash, которая может преобразовать ваши журналы, прежде чем они будут отправлены в тайник. Для наших целей я буду говорить только об обработке данных из Logstash в Elasticsearch.



    Grok-это фильтр внутри Logstash, который используется для разбора неструктурированных данных на что-то структурированное и подлежащее запросу. Он находится поверх регулярного выражения (regex) и использует текстовые шаблоны для сопоставления строк в файлах журналов.


    Как мы увидим в следующих разделах, использование Grok имеет большое значение, когда речь заходит об эффективном управлении журналами.


    Без Grok ваши данные журнала Неструктурированы



    Без Grok, когда журналы отправляются из Logstash в Elasticsearch и визуализируются в Kibana, они появляются только в значении сообщения.


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


    Неструктурированные данные из логов


    localhost GET /v2/applink/5c2f4bb3e9fda1234edc64d 400 46ms 5bc6e716b5d6cb35fc9687c0

    Если вы внимательно посмотрите на необработанные данные, то увидите, что они на самом деле состоят из разных частей, каждая из которых разделена пробелом.


    Для более опытных разработчиков вы, вероятно, можете догадаться, что означает каждая из частей и что это сообщение журнала от вызова API. Представление каждого пункта изложено ниже.


    Структурированный вид наших данных


    • ​ localhost == environment
    • ​ GET == method
    • ​ /v2/applink/5c2f4bb3e9fda1234edc64d == url
    • ​ 400 == response_status
    • ​ 46ms == response_time
    • ​ 5bc6e716b5d6cb35fc9687c0 == user_id

    Как мы видим в структурированных данных, существует порядок для неструктурированных журналов. Следующий шаг – это программная обработка необработанных данных. Вот где Грок сияет.


    Шаблоны Grok


    Встроенные шаблоны Grok


    Logstash поставляется с более чем 100 встроенными шаблонами для структурирования неструктурированных данных. Вы определенно должны воспользоваться этим преимуществом, когда это возможно для общих системных журналов, таких как apache, linux, haproxy, aws и так далее.


    Однако что происходит, когда у вас есть пользовательские журналы, как в приведенном выше примере? Вы должны построить свой собственный шаблон Grok.


    Кастомные шаблоны Grok


    Нужно пробовать, чтобы построить свой собственный шаблон Grok. Я использовал Grok Debugger и Grok Patterns.


    Обратите внимание, что синтаксис шаблонов Grok выглядит следующим образом: %{SYNTAX:SEMANTIC}


    Первое, что я попытался сделать, это перейти на вкладку Discover в отладчике Grok. Я подумал, что было бы здорово, если бы этот инструмент мог автоматически генерировать шаблон Grok, но это было не слишком полезно, так как он нашел только два совпадения.



    Используя это открытие, я начал создавать свой собственный шаблон на отладчике Grok, используя синтаксис, найденный на странице Github Elastic.



    Поиграв с разными синтаксисами, я наконец-то смог структурировать данные журнала так, как мне хотелось.



    Ссылка на отладчик Grok https://grokdebug.herokuapp.com/


    Исходный текст:


    localhost GET /v2/applink/5c2f4bb3e9fda1234edc64d 400 46ms 5bc6e716b5d6cb35fc9687c0

    Pattern:


    %{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id}

    То что получилось в итоге


    {
      "environment": [
        [
          "localhost"
        ]
      ],
      "method": [
        [
          "GET"
        ]
      ],
      "url": [
        [
          "/v2/applink/5c2f4bb3e9fda1234edc64d"
        ]
      ],
      "response_status": [
        [
          "400"
        ]
      ],
      "BASE10NUM": [
        [
          "400"
        ]
      ],
      "response_time": [
        [
          "46ms"
        ]
      ],
      "user_id": [
        [
          "5bc6e716b5d6cb35fc9687c0"
        ]
      ]
    }

    Имея в руках шаблон Grok и сопоставленные данные, последний шаг — добавить его в Logstash.


    Обновление файла конфигурации Logstash.conf


    На сервере, на котором вы установили стек ELK, перейдите к конфигурации Logstash:


    sudo vi /etc/logstash/conf.d/logstash.conf

    Вставьте изменения.


    input { 
      file {
        path => "/your_logs/*.log"
      }
    }
    filter{
      grok {
        match => { "message" => "%{WORD:environment} %{WORD:method} %{URIPATH:url} %{NUMBER:response_status} %{WORD:response_time} %{USERNAME:user_id}"}
      }
    }
    output {
      elasticsearch {
        hosts => [ "localhost:9200" ]
      }
    }

    После сохранения изменений перезапустите Logstash и проверьте его состояние, чтобы убедиться, что он все еще работает.


    sudo service logstash restart
    sudo service logstash status

    Наконец, чтобы убедиться, что изменения вступили в силу, обязательно обновите индекс Elasticsearch для Logstash в Kibana!



    С Grok ваши данные из логов структурированы!



    Как мы видим, на изображении выше, Grok способен автоматически сопоставлять данные журнала с Elasticsearch. Это облегчает управление журналами и быстрый запрос информации. Вместо того чтобы рыться в файлах журналов для отладки, вы можете просто отфильтровать то, что вы ищете, например среду или url-адрес.


    Попробуйте дать Grok expressions шанс! Если у вас есть другой способ сделать это или у вас есть какие-либо проблемы с примерами выше, просто напишите комментарий ниже, чтобы сообщить мне об этом.


    Спасибо за чтение — и, пожалуйста, следуйте за мной здесь, на Medium, для получения более интересных статей по программной инженерии!



    P.S Ссылка на источник


    Телеграм-канал по Elasticsearch

    Комментарии 7

      0
      %{NUMBER:response_status} %{NUMBER:response_time}ms %{USERNAME:user_id}"}
      и можно будет графики про время ответа строить
        +2

        Вот мне интереснее, что делать с логами, в которых формат записей то и дело чередуется. То это что-то легко разбираемое, то несколько строк просто текста и пара строк совсем другого формата.
        Например, в ySoft SafeQ такие логи, в Oktell. Да много где ещё, наверное.

          –1
          Это плохие логи. Каждую посылку придётся вычищать от символов возврата картеки и новой строки, конкатенировать в одно сообщение. Потом заново бить на сообщения по шаблону (времени скорее всего) и обрабатывать тем или иным фильтром. Вообще таким приложениям, которые пишут в логи как попало, уготовлено отдельное место в аду. Многострочные эксепшены необходимо хотя бы в логи не отправлять или отправлять в «другие» логи, а не те, которые отправляются в эластик.

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

            Согласен, что логи плохие. К сожалению, не всегда на это повлиять можно.

            0
            Можно написать несколько шаблонов GROK и подставлять их по очереди. Подходящий и обработает нужное.
            Либо построить более разветвлённую логику и по анализу входящих данных подставлять нужные варианты.
            +1
            В статье написано про grok фильтр, но нет упоминания про template, который пригодится для правильного определения типа полей и другой информации при создании индекса в Elasticsearch. Если парсить текстовые файлы, то достаточно встроенного функционала Elasticsearch Ingest Pipeline + Filebeat.
              0
              Логсташ и Эластик довольно умные и редко ошибаются в типах. Если только не всякий мусор прилетает. В основном географические координаты приходится темплейтом переопределять, чтоб нормальные типы geo_* записывались.

              Что до статьи, то это очередной перевод «ввод в профессию». Лучше бы нюансы написания конфигов логсташа описали. Приоритеты применения фильтров. Примеры разбора xml сообщений. Вычленения дополнительных полей и тегов.

              Есть чудесный (во всех смыслах и багах тоже) фильтр translate. Лучше бы про него статью, а не про заезженный grok

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое