Просмотр архивных логов apache c помощью Logstash+Elastisearch+Kibanа

Приветствую.

Нет так давно передо мной встала задача пробежаться по старым логам apache. Надо было сделать выборку по нескольким IP адресам, отыскать некоторые аномалии и попытки SQL-injection'ов. Логов было не так много, порядка миллиона строк и можно было спокойно всё сделать стандартным набором grap-awk-uniq-wc итд.

Поскольку я уже какое-то (больше года) время пользуюсь связкой Logstash-Elasticsearch-Kibana для анализа-просмотра всевозможных логов, то решил ей воспользоваться и в данной ситуации.

Краткое описание основных компонентов системы.

Logstash — бесплатная open-source программа на java для сбора и нормализации логов. Может принимать логи либо с локальных файлов, либо через tcp/udp порты. На момент написания статьи, разных входных (input) фильтров насчитывается 26. Есть даже входной модуль, для сбора сообщений из twitter'а или irc.

Elasticsearch — бесплатный open-source поисковый сервер основанный на Apache Lucene. Быстрый, легко настраиваемый и очень масштабируемый.

Kibana — веб-интерфейс написанный на ruby, для отображения данных из Elasticsearch. Простая настройка, но множество функций — поиск, графики, stream.



1. Elasticsearch


1.1 Скачиваем Elasticsearch (размер 16MB):
Важно заметить, что для Logstash версии 1.1.9 Elasticsearch должен быть именно версии 0.20.2.
# wget download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.20.2.tar.gz

1.2 Распаковываем файл:
# tar -zxf elasticsearch-0.20.2.tar.gz
Желающие поразить окружающих могут добавить ключ «v» :)

1.3 По большому счёту можно запускать Elasticsearch и с заводскими настройками. Но я всё же меняю некоторые параметры.
Заходим любимым текстовым редакторов в файл настроек:
# vi elasticsearch-0.20.2/config/elasticsearch.yml

Список моих изменений для standalone решения:
cluster.name: logs
index.number_of_replicas: 0
path.data: /elasticsearch/elasticsearch-0.20.2/data
path.work: /elasticsearch/elasticsearch-0.20.2/work
path.logs: /elasticsearch/elasticsearch-0.20.2/logs
bootstrap.mlockall: true
discovery.zen.ping.multicast.enabled: false
Перед запуском Elasticsearch убедитесь, что каталоги прописанные в path.data, path.work и path.logs существуют.

1.4 Запускаем Elasticsearch в foreground режиме, что бы удостовериться, что сервер корректно работает:
# ./bin/elasticsearch -f
Если видим строку подобную этой, значит сервер запустился
[2013-01-11 1151:35,160][INFO ][node                     ] [Virgo] {0.20.2}[17620]: started

1.5 Для запуска Elasticsearch в фоновом (daemon) режиме достаточно убрать ключ "-f"
# ./bin/elasticsearch

Если на вашем сервере появились два tcp порта 9200 и 9300 в режиме LISTEN, то это значит Elasticsearch готов к работе.

2. Logstash


2.1 Скачиваем свежую версию Logstash 1.1.9 (размер 60MB)
# wget logstash.objects.dreamhost.com/release/logstash-1.1.9-flatjar.jar

2.2 Создаём конфигурационный файл (apache.conf) для принятия архивных логов apache, их нормализации и занесением в базу Elasticsearch:
input {
  tcp {
    type => "apache-access"
    port => 3338
  }
}
filter {
  grok {
    type => "apache-access"
    pattern => "%{COMBINEDAPACHELOG}"
  }
  date {
    type => "apache-access"
    timestamp => "dd/MMM/yyyy:HH:mm:ss Z"
  }
}
output {
  elasticsearch {
    embedded => false
    cluster => logs
    host => "172.28.2.2"
    index => "apache-%{+YYYY.MM}"
    type => "apache-access"
    max_inflight_requests => 500
  }
}


Краткое описание некоторых параметров:
port => 3338
В нашем случае Logstash будет слушать на tcp порту 3338. На него мы будем посылать netcat'м логи apache.

cluster => logs
указываем название кластера, которое мы прописали в cluster.name: в настройках Elasticsearch

host => "172.28.2.2"
ip адрес на котором бегает Elasticsearch

index => "apache-%{+YYYY.MM}"
в моём случае суточных логов apache не так много около 40000, поэтому месячного индекса достаточно. Если же логов в сутки по 500000 или больше, тогда уместнее создать суточный индекс «apache-%{+YYYY.MM.dd}»

2.3 Запускаем Logstash
# java -Xmx64m -jar logstash-1.1.9-flatjar.jar agent -f ./apache.conf

Проверяем, что Logstash запущен:
# netstat -nat |grep 3338
Если порт 3338 присутствует, значит Logstash готов принимать логи.

2.4 Начинаем посылать старые логи apache Logstash'у
# gunzip -c archived.apache.log.gz |nc 127.0.0.1 3338
Как быстро зальются все логи, зависит от многих параметров — CPU, RAM, количество логов.
В моём случае 600 тысяч строк логов полностью залились в базу за 4 минуты. Так что your mileage may vary.

2.5 Пока идёт процесс закачивания логов, можно проверить попадают ли данные в базу Elasticsearch.
Для этого в браузере введите elasticsearch_ip:9200/_status?pretty=true, если вы найдёте там строки подобные этой:
"index" : "apache-2011.09"
значит всё работает как и требовалось.

3. Kibana


3.1 Устанавливаем Кибану:
git clone --branch=kibana-ruby github.com/rashidkpc/Kibana.git
cd Kibana
gem install bundler
bundle install

Если вы находитесь за прокси сервером, то перед командой «git clone...» укажите ваш прокси сервер:
git config --global http.proxy proxy.domain.com:3128

3.2 Конфигурация Kibana
# vi KibanaConfig.rb
Настройки, которые возможно потребуют изменений:
Elasticsearch = "localhost:9200"
KibanaPort = 5601
KibanaHost = '172.28.2.2'
Smart_index_pattern = 'apache-%Y.%m'
Smart_index_step = 2592000


3.3 Запуск Kibana
# ruby kibana.rb

После успешного запуска, на экране делжен появиться подобный текст:
== Sinatra/1.3.3 has taken the stage on 5601 for development with backup from Thin
>> Thin web server (v1.5.0 codename Knife)
>> Maximum connections set to 1024
>> Listening on 172.28.21.21:5601, CTRL+C to stop


3.4 Начинаем просматривать логи
В браузере вводим адрес http://172.28.21.21:5601 и получаем удобный, быстрый интерфейс для просмотра старых логов apache.

Для желающих посмотреть что такое Kibana+Logsatsh+Elasticsearch имеется демо страница http://demo.logstash.net/

Спасибо за внимание,
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 25

    0
    Скопировал урл из первой строки лога, ввёл в поисковую строчку, ничего не нашлось :(
    Вы не в курсе, можно ли запилить это так, чтобы люцен проиндексировал содержимое строчки лога? Масштабироваться, на сколько я знаю, он должен действительно неплохо.
      0
      «ввёл в поисковую строчку» — это имеется ввиду поисковая строка в Kibana или что-то другое?

      Индексация всех данных и так присходит. При использовании grok фильтра (в моём примере), строка разбивается на блоки. Каждый блок имее название поля и данные этого поля. По любым полям можно осеществлять поиск.
      Т.е. если в поиск в Kibana вписать @fields.request:*zip*, то должны появиться все строки, где в поле request присутствуют в любом месте буквы zip. По дефолту Kibana ищет в 15 последних минутах логов. Что бы найти отовсюду, в левом дропдауне надо выбрать «All Time».
        0
        Ага, туда. ОО, если вводить с модификатором @fields.request: и звёздочками — то работает! Не очень очевидно, но сойдёт. И со слешами какая-то беда. Надо будет попробовать залить в него мноооого логов.
      +1
      За статью спасибо.

      Я вот в свое время тоже был озадачен советом посмотреть на счет «индексатора» логов и вебприложения для их просмотра. Те задачи, которые я решал, когда просматривал логи (с помощью awk и еже с ним), мне казалось невозможным сделать через веб-морду в принципе. Ну т.е. грепнуть лог по какой-то ключевой фразе — это понятно и просто везде, и я еще не уверен где лучше смотреть результаты — в консоле с моноширинными шрифтами или в браузере, который будет еще и тормозить со всем красивостями при строках больше 1000.

      А вот грепнуть, и посчитать частоту, или фильтровать и подсчитывать в реальном времени, опять же поискать и аггрегировать, — мне кажется очень проблематичным через вебморду.
        0
        Спасибо, за спасибо :)

        У меня в тестовой базе ES около миллиона записей апаче логов. Поиск типа @fields.request:*mp3* во всех логах занимает около 3х секунд, это с учётом рисования графика и выдаёт около 6000 совпадений. Из найденных результатов скоринг по IP адресам занимает тоже пару секунд.
        Я пока не видел особых тормозов у такой системы при 600-1000 reqs/sec и общем количестве данных почти пол миллиарда. Всё кончено зависит от железа. Много CPU & RAM значительно улучшают скорость.
          0
          Cluster Name
          elasticcluster

          Status green Nodes 3 Docs 3 053 513 952

          Но я не использую logstash, он слишком медленный, не успевает за потоком логов. Пришлось кастомный python код писать самому используя pyes.
            0
            Цифра впечатляет. А какой размер базы и индекса?
              +1
              3 amazon x.large инстанса с 2Тb локального хранилища каждый.
              Занято примерно процентов 60-70 дисков, то есть около 5Тб данных.
              Никакого дублирования данных, чтобы получить максимальную скорость. Если инстанс умирает, теряем треть индекса, но логи архивируются на s3, так что всегда можно поднять архив, если что.
              0
              Хотел уточнить, что именно медленно? Доставка, парсинг или поиск?
              Но что-то у Вас не так, размер нашего индекса 3012959708 документов (и это за 2 недели), работает на 2х серверах — поиск в реальном времени прекрасно работает. Возможно дело в EC2 и производительности, конечно.
              На всякий случай уточню, какие параметры worker и batch у агента? JVM Heap на агенте / сервере?
              Также я не могу поверить что python быстрее чем jruby, на какой реализации писали?
                0
                у меня 3 xlarge инстанса на ec2, все упирается в disk-IO к сожалению. я использую striped LVM над 4 дисками ephemeral storage.
                Насколько я понял, проблема не в языке jruby или python. Проблема в реализации, так как logstash тратил ресурсы и время на обработку входящих данных по TCP. Когда я тестировал, производительности не хватало. Я использовал rsync для транспорта данных и python+pyes c мультипроцессингом docs.python.org/2/library/multiprocessing.html для закачки логов в elasticsearch.

                Я недавно видел в действии реализацию flume+elasticsearch. Мне очень понравилось. Если у меня будет достаточно времени — буду переходить на него.
                  0
                  То есть узкое место при чтении логов на клиенте? Или при обработке на стороне парсера?
                  Я хочу помочь, так-как возможно что-то упущено. Logstash показал себя как очень умереный к ресурсам продукт, и тем более (по логике) должен быть шустрее решений на python (ничего против не имею, просто имхо).
                  Какой у Вас Setup? Centrallized? Расскажите побольше о схеме доставки и обработке логов которую Вы пробовали.
                    0
                    Все достаточно прямолинейно.
                    У меня логи переливаются с серверов на центральный rsync сервер и там парсер на питоне их распарсивает и заливает их в elasticsearch. Парсер стартует по крону каждую минуту и заливает файлы начиная с самых свежих. То есть если логов много, когда активность юзеров выше — теоретически парсер может не успевать. Но это не проблема, так как в более спокойное время он подтягивает старые логи. Получается никакой потери логов даже под высокой нагрузкой.
                      0
                      Я хотел уточнить по поводу конфигурации когда logstash работал медленно, после чего Вы решили использовать свое решение.
                      Я использую logstash (agent) => redis => logstash (master) => elasticsearch, таким образом redis работает как буфер, и если сравнивать с Вашим решением — сильно минимизирует io (у Вас rsync (read io) => rsync (write io) => python (read io) => elastic search (write io). Выходит в версии с logstash->redis->logstash->elasticsearch disk io уменьшено как минимум на 2 раза.
                        0
                        Я пытался использовать logstash вместе с rsyslog, чтобы syslog сразу пересылать по сети в logstash, так как он на серверах уже есть и мы его используем достаточно тесно с zabbix.
                        Не хотелось деплоить агентов logstash вместе с java на сервера, где джава совсем не нужна.
                          0
                          Да, деплоить джаву где она не нужна — это резонная причина, полностью согласен (хотя фактически это особенно ничего не меняет, у меня агенты на windows серверах, и ничего — 150Mb памяти — все что нам нужно :)).

                          Возможно тогда интерес вызовут другие шипперы, например beaver.

                          Logstash действительно хорош, когда дело доходит до обработки и парсинга данных (которые можно шипить чем угодно).
                            0
                            извиняюсь за оффтопик.
                            Чем вы деплоите на видновс сервера? Какую автоматизацию используете?
                              0
                              Если речь идет о logstash — то я создал пакет logstash в репозитории chocolatey, и вся автоматизация сводится к установке пакета. Я использую puppet и ресурс package.
                              Вот статья на тему использования пакетов chocolatey. Там, кстати, рассматривается пакет logstash в качестве примера.
                              А как деплоить — это уже решать Вам, можно все упростить до:

                              cinst logstash
                              

                              Также буду рад ответить на вопросы и выслушать предложения.
          0
          Очень похоже на Graylog2, они также на ElasticSearch перевели хранение самих логов.
            +1
            Да есть немного похожего, правда graylog2 потяжелее будет.
            Проблема последних версий GL2 — у них всего один индекс под логи. При больших объёмах это заметно влияет на тормоза системы. Да и по мелочи там ещё много недоделок — например использование regex в стримах в дополнительных полях.
              0
              Да уж грейлог оказал весьма прожорлив:( Сейчас как раз подумываю об альтернативе и замене его.
                0
                Они оба достаточно прожорливы к сожалению
            0
            Видимо ошибка:
            wget logstash.objects.dreamhost.com/release/logstash-1.1.9-monolithic.jar
            однако:
            java -Xmx64m -jar logstash-1.1.9-flatjar.jar agent -f ./apache.conf

            и еще. Logstash заявляет, что в нем уже есть Elasticsearch. Стоит ли использовать внешний или достаточно внутреннего?
              0
              Спасибо за заметку, исправил.

              У Logstash есть 2 типа файлов — monolithic и flatjar. Flatjar немного по другому запакован и он значительно быстрее готов к работе после запуска.

              По поводу ES. Я всегда использовал сторонний Elasticsearch, так как на нём ещё бегают некоторые мне необходимые вещи.
              Надо будет попробовать на досуге встроенную версию ES.

              Ещё у разработчиков Logstash есть идея сделать Kibana уже вшитой в код, что бы веб-интерфейс был всё таки поудобнее того, что сейчас есть в Logstash'е.
                0
                Eще немного позанудствую. Logstash написан на Ruby и обернут в java. Т.е. используется JRuby. На сайте вроде на нашел прямого упоминания про это, но в видео с презентации на PuppetConf об этом говорится.

          Only users with full accounts can post comments. Log in, please.