Promtail умеет не только считывать логи из файлов, но и прослушивать порт tcp для приема сообщений syslog. К сожалению, возможность приема сообщений syslog по udp сразу демоном promtail у меня не заработала, поэтому принимать syslog сообщения напрямую от сетевого оборудования не получилось. Пришлось на сервере вместе с promtail поставить еще syslog-сервер, который принимает сообщения syslog по стандартному порту udp 514 и пересылает на порт tcp 1514, который уже просматривает promtail. Это оказалась рабочая конструкция.
Для просмотра информации из базы Loki самым естественным инструментом является Grafana. Схематически рассматриваемую модель взаимодействия можно представить так:
Установка Promtail.
Promtail можно установить в систему разными путями. Например, promtail скачивается в систему вместе с кодами loki и собирая loki можно так же собрать и исполняемый файл promtail
Порядок сборки Promtail из исходных кодов с установленным интерпретаторов go в Linux:
# cd /usr/src
# git clone https://github.com/grafana/loki
# cd loki/
# go build ./clients/cmd/promtail
В результате в директории /usr/src/loki появиться исполняемый файл promtail, который нужно переместить на постоянное место:
# mv promtail /usr/local/bin/promtail
Promtail можно развернуть из образа Docker. Это рекомендуемый способ, описанный в документации (https://grafana.com/docs/loki/latest/send-data/promtail/installation/), тут данный способ не рассматривается.
И можно скачать готовый исполняемый файл, собранный под типовые операционные системы. На странице текущего релиза (https://github.com/grafana/loki/releases/) ищем ссылку на файл promtail. Дистрибутив с утилитой называется promtail-linux-amd64.zip. Копируем ссылку на этот файл. 31.01.2024 это релиз 2.9.4 и ссылка https://github.com/grafana/loki/releases/download/v2.9.4/promtail-linux-amd64.zip
Порядок получения готового дистрибутива promtail с сайта:
Скачиваем архив с Promtail, распаковываем и перемещаем на постоянное место:
# cd /usr/src
# curl -O -L https://github.com/grafana/loki/releases/download/v2.9.4/promtail-linux-amd64.zip
# unzip promtail-linux-amd64.zip
# rm -f promtail-linux-amd64.zip
# mv promtail-linux-amd64 /usr/local/bin/promtail
Создаем конфигурационный файл сервиса promtail:
# mkdir /etc/promtail
# touch /etc/promtail/promtail.yaml
Для рассматриваемого случая считывания системных логов и получения информации syslog файл конфигурации будет выглядеть так:
# nano /etc/promtail/promtail.yaml
server:
И можно скачать готовый исполняемый файл, собранный под типовые операционные системы. На странице текущего релиза (https://github.com/grafana/loki/releases/) ищем ссылку на файл promtail. Дистрибутив с утилитой называется promtail-linux-amd64.zip. Копируем ссылку на этот файл. 31.01.2024 это релиз 2.9.4 и ссылка https://github.com/grafana/loki/releases/download/v2.9.4/promtail-linux-amd64.zip
Порядок получения готового дистрибутива promtail с сайта:
Скачиваем архив с Promtail, распаковываем и перемещаем на постоянное место:
# cd /usr/src
# curl -O -L https://github.com/grafana/loki/releases/download/v2.9.4/promtail-linux-amd64.zip
# unzip promtail-linux-amd64.zip
# rm -f promtail-linux-amd64.zip
# mv promtail-linux-amd64 /usr/local/bin/promtail
Создаем конфигурационный файл сервиса promtail:
# mkdir /etc/promtail
# touch /etc/promtail/promtail.yaml
Для рассматриваемого случая считывания системных логов и получения информации syslog файл конфигурации будет выглядеть так:
# nano /etc/promtail/promtail.yaml
server:
http_listen_port: 9080
grpc_listen_port: 0
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: 'http://192.168.1.166:3100/loki/api/v1/push'
scrape_configs:
- job_name: secure
static_configs:
- targets:
- localhost
labels:
job: secure
__path__: /var/log/secure
host: "192.168.1.166"
- job_name: audit
static_configs:
- targets:
- localhost
labels:
job: audit
__path__: /var/log/audit/audit.log
host: "192.168.1.166"
- job_name: php
static_configs:
- targets:
- localhost
labels:
job: php
__path__: /var/log/php-fpm/*.log
host: "192.168.1.166"
- job_name: journal
journal:
max_age: 24h
labels:
job: systemd-journal
host: "192.168.1.166"
- job_name: syslog
syslog:
listen_address: 0.0.0.0:1514
idle_timeout: 60s
listen_protocol: tcp
label_structured_data: yes
labels:
job: "syslog"
relabel_configs:
- source_labels: [__syslog_message_hostname]
target_label: host
- source_labels: [__syslog_message_severity]
target_label: level
Немного о директивах конфигурационного файла.
Директива http_listen_port: 9080 раздела server говорит о том, что сервис Promtail на порту 9080 будет иметь web-морду показа основных данных сервиса.
Раздел positions определяет место, где сервис Promtail будет хранить метки (позиции) уже считанной информации из лог-файлов, чтобы в процессе работы не перечитывать файлы заново и не отправлять в Loki дублирующую информацию.
В разделе clients переменная url определяется путь отправки собранных сервисом данных. Это IP и порт приема данных сервисом Loki.
Раздел scrape_configs описывает задания по считыванию файлов и приема информации сервисом promtail. Задания (job) имеют имя (job_name), тип и метки. Путь считывания файла(ов) задается в подразделе labels оператором __path__.
Одно задание promtail выглядит так:
filename: /tmp/positions.yaml
clients:
- url: 'http://192.168.1.166:3100/loki/api/v1/push'
scrape_configs:
- job_name: secure
static_configs:
- targets:
- localhost
labels:
job: secure
__path__: /var/log/secure
host: "192.168.1.166"
- job_name: audit
static_configs:
- targets:
- localhost
labels:
job: audit
__path__: /var/log/audit/audit.log
host: "192.168.1.166"
- job_name: php
static_configs:
- targets:
- localhost
labels:
job: php
__path__: /var/log/php-fpm/*.log
host: "192.168.1.166"
- job_name: journal
journal:
max_age: 24h
labels:
job: systemd-journal
host: "192.168.1.166"
- job_name: syslog
syslog:
listen_address: 0.0.0.0:1514
idle_timeout: 60s
listen_protocol: tcp
label_structured_data: yes
labels:
job: "syslog"
relabel_configs:
- source_labels: [__syslog_message_hostname]
target_label: host
- source_labels: [__syslog_message_severity]
target_label: level
Немного о директивах конфигурационного файла.
Директива http_listen_port: 9080 раздела server говорит о том, что сервис Promtail на порту 9080 будет иметь web-морду показа основных данных сервиса.
Раздел positions определяет место, где сервис Promtail будет хранить метки (позиции) уже считанной информации из лог-файлов, чтобы в процессе работы не перечитывать файлы заново и не отправлять в Loki дублирующую информацию.
В разделе clients переменная url определяется путь отправки собранных сервисом данных. Это IP и порт приема данных сервисом Loki.
Раздел scrape_configs описывает задания по считыванию файлов и приема информации сервисом promtail. Задания (job) имеют имя (job_name), тип и метки. Путь считывания файла(ов) задается в подразделе labels оператором __path__.
Одно задание promtail выглядит так:
Каждому событию из файла будет присвоено три метки:
• «job» = «audit»
• «host» = «192.168.1.166»
• «filename» = «название файла»
С помощью этих меток впоследствии в интерфейсе grafana можно будет выполнять поиск в базе Loki. Чем больше меток – тем больше в Loki будет объем индексов и тем медленнее будет поиск. В документации Loki рекомендуют создавать новые метки только тогда, когда Вы точно поймете, что они Вам нужны для выборки данных.
В приведенном выше примере конфигурационного файла будут считываться и отправляться в loki данные из файлов.
/var/log/secure
/var/log/audit/audit.log
/var/log/php-fpm/*.log
Каждый файл логов (группа файлов) описана своим заданием.
Для того, чтобы promtail мог обращаться к файлам логов безопасности системы, важно что бы сервис promtail работал от имени пользователя root.
В рассматриваемом файле конфигурации так же определено задание типа journal. Это задание обязывает Promtail подключаться к системному журналу systemd-journal Linux и считывать оттуда информацию для передачи в Loki.
• «job» = «audit»
• «host» = «192.168.1.166»
• «filename» = «название файла»
С помощью этих меток впоследствии в интерфейсе grafana можно будет выполнять поиск в базе Loki. Чем больше меток – тем больше в Loki будет объем индексов и тем медленнее будет поиск. В документации Loki рекомендуют создавать новые метки только тогда, когда Вы точно поймете, что они Вам нужны для выборки данных.
В приведенном выше примере конфигурационного файла будут считываться и отправляться в loki данные из файлов.
/var/log/secure
/var/log/audit/audit.log
/var/log/php-fpm/*.log
Каждый файл логов (группа файлов) описана своим заданием.
Для того, чтобы promtail мог обращаться к файлам логов безопасности системы, важно что бы сервис promtail работал от имени пользователя root.
В рассматриваемом файле конфигурации так же определено задание типа journal. Это задание обязывает Promtail подключаться к системному журналу systemd-journal Linux и считывать оттуда информацию для передачи в Loki.
Для каждого задания по считыванию файлов или данных журнала systemd рекомендую всегда формировать метку, указывающую на IP адрес сервера, откуда поступило лог-сообщение. Благодаря этой информации в базе Loki впоследствии можно будет фильтровать сообщения по хостам.
Директивы конфигурации сервиса приема syslog выглядят так:
Директивы конфигурации сервиса приема syslog выглядят так:
Здесь запускается служба на всех IP адресах сервера на порту 1514 и по протоколу tcp выполняется прием сообщений syslog. Каждому сообщению присваиваются метки:
«job» = «syslog»
«level» = «значение Severity»
«host» = «hostname» (или IP адрес)
Дополнительно если в сообщении syslog будет какая-то структура похожая на ключ=значение, то этот фрагмент текста будет преобразован в метку «Ключ (имя метки)»= «Значение»
Для автозапуска Promtail создаем Systemd Unit.
# nano /etc/systemd/system/promtail.service
Содержимое файла:
[Unit]
Description=Promtail service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/promtail-linux-amd64 -config.file /etc/promtail/promtail.yaml
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
В файле юнита systemd не указан пользователь, который будет владеть процессом. Это сделано умышленно, для того что бы сервис запускался от имени root (это необходимо для считывания логов безопасности Linux, доступных только пользователю root).
После редактирования файла юнита выполняем:
# systemctl daemon-reload
Запускаем сервис и проверяем его работу
# systemctl start promtail
# systemctl enable promtail
# systemctl status promtail
# ss -nltup | grep 9080
Открываем порт 9080 в файрволле и проверяем применение правил:
# firewall-cmd --permanent --add-port=9080/tcp
# firewall-cmd --reload
# firewall-cmd --list-all
Теперь обратившись к Url http://<IP-адрес>:9080 мы увидим информацию о работе сервиса Promtail:
# /usr/local/bin/promtail --dry-run --inspect --config.file=/etc/promtail/promtail.yaml
Опция --dry-run означает, что данные, полученные promtail не будут отправляются в Loki и лог файл будет читаться с одного и тоже места. Опция --inspect заставит promtail выводить отладочную информацию в консоль. При поступлении новых логов информация и назначаемые информации метки будут в консоли:
Установка и настройка rsyslog.
Rsyslog необходим для того, что бы принимать syslog сообщения по стандартных портам оборудования (514 порт по tcp и udp) и передавать в Loki на порт 1514 tcp. При этом rsyslog форматирует сообщения, которые могут иметь различный формат у разных вендоров. В Loki данные попадают в едином формате.
В системе уже может быть установлен rsyslog по умолчанию, или вместо rsyslog может быть установлен syslog-ng. Поэтому перед установкой rsyslog, необходимо удалить старые версии rsyslog и syslog-ng. Затем провести установку rsyslog в систему:
# yum install rsyslog
# systemctl start rsyslog
# systemctl enable rsyslog
Главный конфигурационный файл rsyslog лежит тут: /etc/rsyslog.conf
Для того что бы rsyslog принимал сообщения по 514 порту (tcp и udp) и перенаправлял их на порт 1514 tcp в едином формате, необходимо добавить следующие директивы в файл конфигурации:
# nano /etc/rsyslog.conf
После директивы include(file="/etc/rsyslog.d/*.conf" mode="optional") нужно вставить:
module(load="imudp")
input(type="imudp" port="514" ruleset="sendRemote")
module(load="imtcp")
input(type="imtcp" port="514" ruleset="sendRemote")
#module(load="omfwd")
ruleset(name="sendRemote") {
action(type="omfwd" target="10.10.49.166" port="1514" protocol="tcp"
action.resumeRetryCount="-1"
Template="RSYSLOG_SyslogProtocol23Format"
TCP_Framing="octet-counted" KeepAlive="on" RebindInterval="60"
queue.type="linkedList"
queue.saveOnShutdown="on"
queue.maxDiskSpace="1g"
queue.fileName="fwdRule1")
}
В конфигурации закомментирована одна строчка - #module(load="omfwd"). Дело в том, что в некоторых версиях rsyslog, требуется прописывать данную строку явно, в современных версиях rsyslog модуль перенаправления omfwd загружается при старте rsyslog и отдельное указание на загрузку этого модуля не требуется.
Примечание 1. Если модуль интегрирован в rsyslog, его не нужно загружать, а мы пытаемся это сделать директивой module(load="omfwd") возникнет ошибка:could not load module 'omfwd', errors: trying to load module /usr/lib64/rsyslog/omfwd.so: /usr/lib64/rsyslog/omfwd.so: /usr/lib64/rsyslog/omfwd.so: cannot open shared object file: No such file or directory [v8.2102.0-117.el9 try https://www.rsyslog.com/e/2066 ]
Примечание 2. Директива RebindInterval="60", описанная в конфигурации, обязывает демон rsyslog каждые 60 секунд пересоздавать соединение tcp с удаленным сервером, куда выполняется перенаправление. Если этого не делать, Loki, если не будет видеть активности на приеме, закроет Tcp соединение через 2 минуты (120 секунд по умолчанию). В логах rsyslog при этом можно будет наблюдать:
omfwd: remote server at 10.10.49.166:1514 seems to have closed connection. This often happens when the remote peer (or an interim system like a load balancer or firewall) shuts down or aborts a connection. Rsyslog will re-open the connection if configured to do so (we saw a generic IO Error, which usually goes along with that behaviour). [v8.2102.0-117.el9 try https://www.rsyslog.com/e/2027 ]
Grafana. Настройка представления данных Loki.
После установки Gragana, для отображения данных Loki в интерфейсе необходимо выполнить подключение источника данных – Loki и создать дашборд, показывающий эти данные.
Для подключения источника, выбираем в меню «Connections» —> «Data sources»
Теперь необходимо выбрать тип источника данных. В поисковой строке набираем «loki» и кликаем по найденному драйверу:
В открывшейся форме добавления нового источника вписываем имя источника, например «loki», затем в поле URL вписываем путь до порта, прослушиваемого сервисом loki. Например http://192.168.1.166:3100. Остальные настройки можно оставить по умолчанию. Прокручиваем страницу вниз и нажимаем кнопку «Save & test». После этого произойдет соединение с базой Loki и новый источник данных отобразиться в меню Grafana.
Если что-то пойдет не так и соединение не будет установлено, возникнет ошибка «Unable to connect with Loki. Please check the server logs for more details»
При удачном соединении мы должны увидеть:
Теперь нужно создать типовой Dashboard для показа данных о логах. Для этого заходим в меню Dashboards и нажимаем кнопку «Create Dashboars»
На следующем этапе нужно выбрать источник данных. В нашем случае – это источник «loki», который мы подключили ранее
На нижней панели добавляются запросы, которые будут работать с источником данных «Loki». Для отображения количества лог-записей системного журнала systemd, поступивших за 1 минуту в базу Loki нужно задать следующее:
Метки (Label filter): job=system-journal,
Операции: Count over time, Range, 1m
То есть тут задается фильтр меток по которым из базы Loki будут извлечены только записи, обладающие меткой «job»=«system-journal», а затем указывается операция преобразования этой выборки – показывать количество записей за указанный временной интервал.
Для проверки работы выборки справа представлена кнопка «Run query».
Метки (Label filter): job=system-journal,
Операции: Count over time, Range, 1m
То есть тут задается фильтр меток по которым из базы Loki будут извлечены только записи, обладающие меткой «job»=«system-journal», а затем указывается операция преобразования этой выборки – показывать количество записей за указанный временной интервал.
Для проверки работы выборки справа представлена кнопка «Run query».
Для сохранения этого представления на дашборде на правой панели нужно задать имя представления (Title), например «system-journal count», и нажать «Apply»:
После этого представление добавиться на дашбоард. Представление не будет занимать все пространство дашбоарда:
Что бы растянуть представление на всю ширину, нужно ухватить мышкой за правый нижний угол панели представления и растянуть картинку во всю ширину:
Теперь нужно сохранить дашборд в памяти Grafana. Для этого нужно нажать на панели вверху справа кнопку сохранения «Save dashboard»
Добавим на дашборд кроме графика количества логов еще и таблицу с записями логов. Для этого сверху на панели инструментов нажимаем «Add»--> «Visualization»
Для того что бы добавить панель представления с таблице логов нужно выбрать тип представления. Тип представления выбирается справа из выпадающего списка. Для показа логов нужно выбрать тип «Logs»:
Затем задаем имя представления (Title), например «systemd-journal logs». Для показа времени события (времени прихода лога) делаем активным переключатель Time. Для того что бы длинные записи лога переносились на новую строку активируем переключатель «Wrap lines»:
После этого в нижней панели слева формируем запрос к базе, который будет работать на этом представлении.
Указываем, что нужно отображать записи, обладающей меткой «job»=«system-journal». Для проверки отображения данных нажимаем «Run query»
Указываем, что нужно отображать записи, обладающей меткой «job»=«system-journal». Для проверки отображения данных нажимаем «Run query»
На панели сверху должны отобразиться логи. Для сохранения этого представления нужно нажать кнопку «Apply», расположенную сверху справа:
После добавления нового представления на дашборд нужно еще раз сохранить дашборд нажав «Save dashboard» и еще раз «Save»
Для удобства работы с dashboard можно ввести сразу на этом дашборде доступ к показу данных с конкретного сервера и фильтр поиска по тексту лога, так как сейчас нет возможности отделить в потоке логов логи от разных серверов и искать информацию внутри логов.
Для этого нужно на дашборд добавить переменные. Это делается в настройках дашборад. Нужно нажать кнопку «Dashboard settings»:
Далее нажимаем кнопку добавления переменной «Add variable»
Нам нужно добавить две переменные. Первая переменная будет являться выпадающим списком, который содержит все IP адреса хостов, откуда в Loki валяться логи. Вторая переменная будет обычным текстовым полем, чтобы задавать текст, который нужно искать в теле лог-сообщения.
Для добавления выпадающего списка хостов (IP адресов источника логов) тип переменной должен быть «Query». Затем нужно задать:
Имя переменной - «Name», например «host»
Метку переменной (ту что будет отображаться на дашборде) – «Label», например «host».
Источник данных, как будет заполняться переменная. В нашем случае выпадающий список будет формироваться из уникальных меток «host» источника «Loki». Для значения переменной будет браться значение меток («Label values»)
Для добавления выпадающего списка хостов (IP адресов источника логов) тип переменной должен быть «Query». Затем нужно задать:
Имя переменной - «Name», например «host»
Метку переменной (ту что будет отображаться на дашборде) – «Label», например «host».
Источник данных, как будет заполняться переменная. В нашем случае выпадающий список будет формироваться из уникальных меток «host» источника «Loki». Для значения переменной будет браться значение меток («Label values»)
Для добавления второй переменной нажимаем «New variable». Для добавления простой переменной, которую будем использовать для поиска внутри лог-сообщения нужно добавить переменную типа «Text box». Затем нужно задать
Имя переменной - «Name», например «search_txt»
Метку переменной (ту что будет отображаться на дашборде) – «Label», например «search»
Имя переменной - «Name», например «search_txt»
Метку переменной (ту что будет отображаться на дашборде) – «Label», например «search»
Остальное оставляем по умолчанию и нажимаем «Apply»
Теперь переменные нужно внедрить на дашборд. Сами поля для выбора-задания переменных уже появились на дашборде, но пока они не работают. Для вплетения переменных в запросы данных Loki на дашборде справа на панели представления количества логов в минуту вызываем меню и выбираем «Edit»
Теперь необходимо отредактировать цепочку запроса добавив условие, связанное с переменными. В цепочку меток добавляем «host» = «$host», для поиска внутри логов вписываем имя переменной в поле Line contains – «$search_txt». Упоминание переменных в запросах нужно делать добавляя к именам переменных символ доллара.
Для второго представления, показывающего сами логи, нужно сделать аналогичное действие. Выбрать меню редактирования представления и добавить в запрос переменные $host и $search_txt следующим образом. Затем сохраниться нажав «Apply»
После данных манипуляций необходимо сохранить изменения в дашборде нажав «Save Dashboard» и затем «Save».
Теперь на дашборде можно проводить поиск логов по IP адресу источника и по произвольному тексту в логах
Дашборд – это панель, на которой должно показываться укрупненно ход текущей работы системы. Если что-то пойдет не так, на графиках, в цифрах и пр, оператор, как правило это видет и переходит к детальному анализу логов. Детальный анализ логов и поиск по базе локи удобно проводить не на дашборде, а в специально предназначенном разделе Grafana – Explore. Перейти в этот раздел можно из меню слева:
Результат запросов – график количества записей логов и список логов, соответствующий запросу будет представлен ниже на этой же странице