В регулярном выражении должен быть хотя бы один именованный захват (?<NAME> PATTERN)
Если в рег выражении есть захват с именем «time», его можно настроить с помощью «time_key» параметра, оно используется как время события. Вы можете указать формат времени в параметре «time_format»
<parse> @type regexp expression /.../im </parse> <!-- Пример рег выражения, по блокам --> expression ^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3})[ ]+(?<thread>\[.*\]+) (?<level>[^ ]+)[ ]+(?<class>[^ ]+)[ ]+\-[ ]+(?<message>.*) /^ (?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}) <!-- Блок с временем --> [ ]+ <!-- один и болеепробелов --> (?<thread>\[.*\]+) <!-- поток, в квадратных сбоках --> [ ]+ (?<level>[^ ]+) <!-- Следующий блок, ограничен пробелами --> [ ]+ (?<class>[^ ]+) [ ]+ \- [ ]+ (?<message>.*) <!-- Все оставщееся --> /
Парсер для многострочного варианта
Модуль «multiline» является аналогом «regexp» только для многострочного использования
Дока
<source> @type tail <parse> @type multiline format_firstline /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}[ ]+.*/ format1 /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3})[ ]+(?<thread>\[.*\]+) (?<level>[^ ]+)[ ]+(?<class>[^ ]+)[ ]+\-[ ]+(?<message>.*)/ </parse> path C:\myapp\logs\myapp.log pos_file C:\td-agent\pos\myapp.pos tag myapp_log </source>
#### ## Output descriptions: ## <source> @type tail <parse> @type regexp expression /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3})[ ]+\[(?<thread>[^ ]+)\][ ]+(?<level>[^ ]+)[ ]+(?<class>[^ ]+)[ ]+\- (?<message>.*)/ </parse> path C:\my_service\logs\my_service.log pos_file C:\td-agent\pos\my_service.pos tag my_service_log </source> <match my_service_log> @type record_modifier <record> host "2.2.2.0" </record> tag my_service </match> #<filter my_service> # @type grep # <regexp> # key level # pattern /info/i # </regexp> #</filter> <match my_service> @type elasticsearch host 1.1.1.1 port 9200 logstash_format true logstash_prefix my_service user -- password -- reconnect_on_error true reload_on_failure true reload_connections false log_es_400_reason true request_timeout 15s <buffer> @type memory chunk_limit_records 1000 chunk_limit_size 2M queue_limit_length 100 queued_chunks_limit_size 200 overflow_action block retry_max_interval 10 retry_randomize true retry_max_times 3 flush_interval 5 flush_mode interval flush_thread_count 5 </buffer> </match>
Файл лежит в папке «etc/td-agent/config.d/«
а штатный конфиг, «td-agent.conf», содержит строку »@include config.d/*.conf»
# Скрипт для установки 4ой версии $ curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent4.sh | sh
<Source> → <Match(что делать)> <Source> → <Match(что делать)>
Source - информация об источнике данных
Match - информация о том куда передавать полученные данные
Include - информация о типах файлов
System - настройки системы
Откуда брать данные. Для подключения источников есть разные плагины (например «type http» или «type forward»). Для каждого источника отдельный блок
Каждое событие передается маршрутизатору сообщений, каждое событие содержит «tag, time и record»
На основании «tag» принимается решение куда перенаправлять событие, а record содержит сами данные в формате json
Указывается по какому признаку отбирать события для полседующей обработки, тоже используются спец плагины
Например:
#Берём события, помеченные тэгами "myapp.access" #и сохраняем их в файле/var/log/fluent/access.%Y-%m-%d #данные можно разбивать на порции с помощью опции time_slice_format. <match myapp.access> type file path /var/log/fluent/access </match>
Есть ряд комбинаций по маске, звездочки, фигурные скобки
- символ * означает соответствие любой части тэга (если указать <match a.*>, то a.b будет соответствовать заданному условию, а a.b.c — нет); - ** означает соответствие любому тэгу (если указать <match **>, то заданному условию будут соответствовать и a, и a.b., и a.b.c); - {x, y, z} означает соответствие по крайней мере одному из тэгов, указанных в фигурных скобках (если указать <match {a, b}>, то а и b будут соответствовать заданному условию, а с — нет); - фигурные скобки можно использоовать в сочетании с символами * и **, например: <match {a, b}. c.*> или <match {a.*, b}.c>*; - <match a b> означает соответствие тэгам a и b одновременно; - <match a.** b.*> означает соответствие тэгам a, a.b и a.b.c (первая часть) и b.d (вторая часть).
События матчатся друг за другом и похоже дальше не передаются, т.к. самые общие правила должны быть внизу
В таком подходе парсятся все логи в указанном расположении, а для разделения в матче задаем «service_name ${»#{tag_parts[3]}«}», это 3ий элемент в пути, тут будет имя папки
«logstash_prefix» указанный в ELK это префикс по которому будем отбирать в кибане
Не забываем при мерже нескольких конфигов, что матчи с одинаковым именем могут пересекаться и не будет правильно работать, используется первый подходящий, дальше не идет
<source> @type tail format multiline format_firstline /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}/ format1 /^(?<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})[ ]+\[(?<thread>[^ ]+)?\][ ]+(?<level>[^ ]+)[ ]+(?<class>[^ ]+)[ ]+\- (?<message>.*)/ time_format %F %T.%L path "/opt/BIN/Service_*/log/my_service.log" tag my_tag.* read_from_head true pos_file /var/log/td-agent/pos/FileMultiplicator.pos refresh_interval 10s rotate_wait 0s emit_unmatched_lines true </source> <filter my_tag**> @type grep <regexp> key level pattern /ERROR/ </regexp> </filter> <match my_tag**> @type record_modifier <record> host "#{Socket.gethostname}" service_name ${"#{tag_parts[3]}"} </record> tag elkFM </match> <match elkFM> @type elasticsearch host 10.10.10.10 port 9100 logstash_format true logstash_prefix my_prefix user ==== password ==== reconnect_on_error true reload_on_failure true reload_connections false <buffer > @type memory chunk_limit_size 12m queue_limit_length 50 overflow_action block retry_max_interval 10 retry_randomize true retry_max_times 3 flush_interval 5 flush_mode interval flush_thread_count 5 </buffer> </match>