Имеется два QA сервера — один в дата-центре Ирландии, другой — в США.
Требуется собирать с них логи catalina.out
и передавать на центральный сервер Logstash.
Повторяем установку Logstash Forwarder, как это описано в посте ELK: Elasticsearch+Logstash+Kibana — добавление удалённого хоста и настройка Logstash Forwarder — и приступаем к настройке, например — файл конфигурации с QA-сервера из США:
{ "network": { "servers": [ "ec2-54-***-***-47.compute-1.amazonaws.com:5001" ], "ssl ca": "/etc/pki/tls/certs/logstash-forwarder.crt", "timeout": 15 }, "files": [ { "paths": [ "/var/log/tomcat7/catalina.out" ], "fields": { "type": "n-qa-vir-catalina" } } ] }
Тут:
servers
— куда отправлять логи;ssl ca
— публичная часть сертификата сервера;timeout
— время ожидания ответа от Logstash сервера;paths
— файл лога;fields
— указываем в поле type имя, по которому в дальнейшем будем сортировать логи.
Переходим к серверу.
В файл шаблонов (в данном примере это /opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-0.3.0/patterns/grok-patterns
) добавляем:
... EVERYTHING (.*) MYTIME %{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:%{MINUTE}:%{SECOND},%{SSS} ...
Создаём два файла файла конфигурации, например:
# ls -l /etc/logstash/conf.d | grep qa -rw-r--r-- 1 root root 812 Sep 11 15:46 n-qa-ire.domain.com.conf -rw-r--r-- 1 root root 812 Sep 11 15:46 n-qa-vir.domain.com.conf
Содержимое одного из них:
input { lumberjack { ssl_certificate => "/etc/pki/tls/certs/logstash-forwarder.crt" ssl_key => "/etc/pki/tls/private/logstash-forwarder.key" port => 5001 type => "n-qa-vir-catalina" add_field => { "server" => "N-QA-VIR" } } } filter { if [type] == "n-qa-vir-catalina" { multiline { pattern => "^s" what => "previous" } grok { match => [ "message", "[%{MYTIME:logTime}] %{LOGLEVEL:logLevel} %{EVERYTHING:logMsg}" ] } fingerprint { source => ["message"] target => "fingerprint" key => "rds-n-qa-vir" method => "SHA1" concatenate_sources => true } } } output { elasticsearch { host => localhost document_id => "%{fingerprint}" index => "logstash-%{type}-%{+YYYY.MM.dd}" } }
Теперь рассмотрим некоторые моменты тут.
add_field => { "server" => "N-QA-VIR" }
— добавляем поле, что бы в Kibana было проще выбирать сервера;if [type] == "n-qa-vir-catalina"
— обычная проверка if/else, что бы обрабатывать логи только с хоста с type == n-qa-vir-catalina;multiline
— для решения проблемы с переносом строк при отображении Java-ексепшенов;fingerprint
— создание «отпечатка» каждой записи, что бы избежать дублирования строк в Kibana;index
в блокеoutput
— создать отдельный индекс для данных каждого хоста.
Содержание
Многострочные записи в Kibana
Для примера — отключим обработку переноса строк при отображении трассировки Java-ошибок:
Каждая новая строка отображается как новая запись.
Что бы избежать этого — используется кодек multiline
:
... multiline { pattern => "^s" what => "previous" } ...
В данном случае указывается, что каждая строка, которая начинается с символа пробела — должна быть «прекреплена» к предыдущей строке.
Это помогает корректно отображать многострочные записи:
Дублирование строк в Kibana
Кроме этой проблемы — возникла ещё одна: при работе с несколькими форвадерами — Elasticsearch добавляет записи от каждого из них, в редзультате чего получается дублирование данных при отображении в веб-интерфейсе:
Что бы избежать этого — используется модуль fingerprint
:
... fingerprint { source => ["message"] target => "fingerprint" key => "rds-n-qa-vir" method => "SHA1" concatenate_sources => true } ...
output { elasticsearch { ... document_id => "%{fingerprint}" ... } }
...
Индексы в Elasticsearch
Что бы просмотреть все созаднные индексы и их размер — можно выполнить:
$ curl 'http://127.0.0.1:9200/_cat/indices?v' health status index pri rep docs.count docs.deleted store.size pri.store.size yellow open logstash-n-qa-vir-catalina-2015.09.13 5 1 827 0 617.4kb 617.4kb yellow open .kibana 1 1 2 1 13.5kb 13.5kb yellow open logstash-2015.09.11 5 1 616153 0 862.8mb 862.8mb yellow open logstash-2015.09.09 5 1 2616 0 1.2mb 1.2mb yellow open logstash-dev-catalina-2015.09.11 5 1 384 85 396.5kb 396.5kb yellow open logstash-n-qa-ire-catalina-2015.09.12 5 1 1 2 7.4kb 7.4kb yellow open logstash-n-qa-vir-catalina-2015.09.11 5 1 817 74 576kb 576kb yellow open logstash-n-qa-ire-catalina-2015.09.13 5 1 190 695 531.8kb 531.8kb yellow open logstash-2015.09.08 5 1 55 0 283.9kb 283.9kb yellow open logstash-n-qa-vir-catalina-2015.09.12 5 1 379 638 991kb 991kb yellow open logstash-n-qa-ire-catalina-2015.09.11 5 1 191 709 584.1kb 584.1kb
Просмотреть данные:
$ curl -XGET 'http://127.0.0.1:9200/logstash-dev-catalina-2015.09.11/_search?pretty=1' | less ... "_index" : "logstash-dev-catalina-2015.09.11", "_type" : "dev-catalina", "_id" : "2e5dbf120deba6dad8cd643fe54864bc6adb9353", "_score" : 1.0, "_source":{"message":"INFO : org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped "{[/access/write-on-collection],methods=[GET]}" onto public java.lang.Boolean com.domain.cloudlibrary.controllers.AccessController.checkUserHasWritePermissionOnCollection(java.lang.String) throws com.netflix.astyanax.connectionpool.exceptions.ConnectionException","@version":"1","@timestamp":"2015-09-11T13:41:36.697Z","type":"dev-catalina","server":"DEV","file":"/var/log/tomcat7/catalina.out","host":"ip-10-122-0-100","offset":"14541646","tags":["_grokparsefailure"],"fingerprint":"2e5dbf120deba6dad8cd643fe54864bc6adb9353"} }, { ...
Удалить индекс:
$ curl -XDELETE 'http://127.0.0.1:9200/logstash-2015.09.08/' {"acknowledged":true}