Сбор syslog с Mikrotik в Loki через Alloy
◽️Alloy или Promtail
◽️Vector или похожий сторонний софт
◽️Сбор логов в текстовый файл с помощью rsyslog и отправка
Решил использовать рекомендуемый самой Графаной Alloy. Конфигурация там простая. В общем случае достаточно будет такой:
loki.write "default" {
endpoint {
url = "http://192.168.137.30:3100/loki/api/v1/push"
}
external_labels = {}
}
loki.source.syslog "syslog_in" {
listener {
address = "0.0.0.0:1514"
protocol = "udp"
labels = { job = "syslog" }
}
forward_to = [loki.process.syslog_process.receiver]
}
loki.process "syslog_process" {
stage.labels {
values = {
remote_ip = "__syslog_connection_ip_address",
hostname = "__syslog_message_hostname",
}
}
forward_to = [loki.write.default.receiver]
}
Принимаем логи по UDP на порт 1514, добавляем немного меток и отправляем в Loki. Кажется, всё просто, но на деле - нет. Если у вас устройство шлёт syslog формата RFC5424, то проблем не будет. Для тестов взял Mikrotik, так как мне важно собирать с них логи. И ничего не получилось. Alloy ожидает логи по стандарту RFC5424 (structured syslog), а Mikrotik шлёт в неполном формате RFC3164. Там логи вида:
system,info,account user admin logged in from 192.168.137.10 via ssh
Alloy ругается на этот лог и не может его распарсить. Почитал документацию alloy и нашёл параметр:
syslog_format = "rfc3164"
Добавил его, логи всё равно не идут. Поменял в Mikrotik формат логов с default на BSD Syslog и логи пошли в Loki, но без информации об адресе отправителя, что очень неудобно, когда у тебя много устройств.
Дальше я реализовал для сбора несколько вариантов, чтобы понять, какой удобнее всего:
◽️Принимать логи в rsyslog в текстовые файлы, а потом забирать их alloy.
◽️Принимать логи в rsyslog насыщать их дополнительными полями и переправлять в alloy.
◽️Использовать для приёма логов Vector. Он принимает микротиковские логи разных форматах.
В первых двух способах парсинг полей недоступен. Чтобы он работал, надо вручную добавлять этап обработки микротиковских логов какой-то регуляркой, выделять поля и передавать структурированные данные в alloy. Я попробовал быстренько это реализовать, но не получилось. Надо разбираться и отлаживать. Задача нетиповая, ИИшки не помогают, предлагают откровенную неработающую лажу. Мне не сказать, что сильно это надо. Конкретно от Микротиков мне важно просто хранить текстовые логи. Их обычно немного, какие-то выборки и группировки не нужны.
Пример того, как записать логи формата syslog с Микротиков в текстовые файлы, я показывал ранее. Сохраняем логи в разные файлы и забираем их с помощью Alloy. Это самый простой способ, что называется - в лоб. Работает надёжно и прост в настройке. Отладка особо не нужна, у меня сразу заработало, в отличие от других вариантов. Фильтрация устройств работает по имени файла, в котором отражён IP.
Второй вариант с пересылкой через rsyslog у меня тоже получился, хоть и не сразу. Пришлось повозиться и отлаживать. Ниже часть конфигурации rsyslog.conf, которая отвечает за приём логов формата default в Mikrotik и пересылку в локальный alloy с добавлением полей до формата RFC5424:
module(load="imudp")
input(type="imudp" port="514" ruleset="to_alloy")
template(name="RFC5424_Wrapper" type="string"
string="<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% mikrotik - - - %msg:2:$%\n"
)
ruleset(name="to_alloy") {
action(type="omfwd"
target="127.0.0.1"
port="1514"
protocol="udp"
template="RFC5424_Wrapper")
stop
}
В итоге самым удобным вариантом оказался Vector. Не хватает лимита по объёму, так что вечером покажу подробно отдельной публикацией.
#loki #mikrotik