Input plugin tail имеет возможность обрабатывать многострочные лог файлы. Достаточно создать PARSER, при помощи которого можно определить первую строку такого сообщения. Все вроде бы работает, но мне захотелось не просто разобрать сообщение по тегам, но и в отдельном теге сохранить всё исходное сообщение.
По идее регулярное выражение, используемое в парсере для лога openfire
2018.04.16 10:48:15 ERROR [pool-2-thread-171]: org.jivesoftware.openfire.filetransfer.proxy.ProxyConnectionManager - Error processing file transfer proxy connection java.io.IOException: Only SOCKS5 supported at org.jivesoftware.openfire.filetransfer.proxy.ProxyConnectionManager.processConnection(ProxyConnectionManager.java:156) ~[xmppserver-4.3.2.jar:4.3.2] at org.jivesoftware.openfire.filetransfer.proxy.ProxyConnectionManager.access$200(ProxyConnectionManager.java:53) ~[xmppserver-4.3.2.jar:4.3.2] at org.jivesoftware.openfire.filetransfer.proxy.ProxyConnectionManager$1$1.run(ProxyConnectionManager.java:125) [xmppserver-4.3.2.jar:4.3.2] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_202] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_202] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_202] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_202] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_202]
должно выглядеть как то так:
^(?<message>(?<time>\d{4}\.\d{2}\.\d{2} \d{2}:\d{2}:\d{2}) (?<loglevel>\w+) {1,2}(?<process>\[[^ ]*\]): .*)
Оказалось, что всё не так просто. Fluent bit находит первую строку, разбирает её, формирует теги. Вроде всё нормально.
Но остальные строки он тупо дописывает к последнему тегу регулярного выражения. И вместо того, что бы поместить их (как я ожидал) в тег message, он добавляет их к тегу process.
Поэтому, после обработки приходится «терять» теги time, loglevel и process используя следующее выражение вместо первого:
^(?<time>\d{4}\.\d{2}\.\d{2} \d{2}:\d{2}:\d{2}) (?<loglevel>\w+) {1,2}(?<process>\[[^ ]*\]): (?<message>.*)
Остальные строки многострочного лога будут добавляться к тегу message, но он не будет содержать время, loglevel и процесс.
Итого, первое регулярное выражение отлично работает с однострочными логами, но не будет работать с многострочными. Вот такая фича.
Добрый день, можно увидеть полный конфиг fluent bit?
Пытаюсь применить парсинг multiline логов, которые идут из докера в kubernetes. Проблема в том что первую строку он «достаёт» из json, а следующие добавляет в json формате.
2019-09-26T15:01:38.746271Z\u0009info\u0009Envoy proxy is NOT ready: 3 errors occurred:\n
{«log»:»\u0009* failed checking application ports. listeners=\»0.0.0.0:15090\»,\»10.110.53.109:42422\»,\»10.99.145.243:8087\»,\»10.99.23.150:443\»,\»10.99.23.150:15020\»,\»10.99.23.150:15032\»,\»10.96.0.1:443\»,\»10.96.0.10:9153\»,\»10.99.23.150:15029\»,\»10.99.23.150:15443\»,\»10.107.243.171:80\»,\»10.96.0.10:53\»,\»10.102.115.169:9898\»,\»10.102.88.236:443\»,\»10.111.40.1:443\»,\»10.108.28.219:15011\»,\»10.97.60.158:443\»,\»10.97.46.154:80\»,\»10.99.23.150:15030\»,\»10.99.23.150:15031\»,\»10.99.23.150:31400\»,\»10.109.121.102:5558\»,\»10.102.88.236:15443\»,\»0.0.0.0:8080\»,\»0.0.0.0:15014\»,\»0.0.0.0:15004\»,\»0.0.0.0:80\»,\»0.0.0.0:5555\»,\»0.0.0.0:15010\»,\»0.0.0.0:9091\»,\»0.0.0.0:5000\»,\»0.0.0.0:443\»,\»0.0.0.0:8060\»,\»0.0.0.0:9090\»,\»0.0.0.0:9901\»,\»0.0.0.0:15001\»\n»,»stream»:»stdout»,»time»:»2019-09-26T15:01:38.747526596Z»}
{«log»:»\u0009* envoy missing listener for inbound application port: 9998\n»,»stream»:»stdout»,»time»:»2019-09-26T15:01:38.747553699Z»}
{«log»:»\u0009* envoy missing listener for inbound application port: 8085\n»,»stream»:»stdout»,»time»:»2019-09-26T15:01:38.747563325Z»}
{«log»:»\n»,»stream»:»stdout»,»time»:»2019-09-26T15:01:38.747569303Z»}
Мой конфиг:
[INPUT]
Name tail
Tag kube.*
Path /var/log/containers/nc-wf-*.log
Multiline On
Parser_Firstline audit-firstline-json
DB /var/log/flb_kube.db
Mem_Buf_Limit 5MB
Skip_Long_Lines On
Refresh_Interval 10
[PARSER]
Name audit-firstline-json
Format regex
Regex ^{«log»:»(?(?\d{4}-\d{2}-\d{2}( |\T)\d{2}:\d{2}:\d{2}(.|,)\d{3,})(?:(\\»)|[^»]){9}(?:(\\»)|[^»])*)»
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Fluent Bit по определению не умеет парсить строки, кроме первой, у multiline логов.
В Вашем случае, случае куберенетес я бы переписал приложение или настроил его или надавил бы на автора, что бы оно кидало лог одной Json строкой. И дальше использовал стандартный фильтр fluent bit — kubernetes с включенным параметром Merge_Log on. Это параметр заставляет fluent bit самостоятельно разбирать json log и формировать поля. Кроме того, этот фильтр вытащит всю необходимую информацию по контейнеру из api kubernetes. Ну и парсер можно использовать стандартный, его задача вытащить из лога поле time.