Grafana Loki

Thank you for reading this post, don't forget to subscribe!

Grafana Loki

систе­ма для сбо­ра и обра­бот­ки логов. Офи­ци­аль­ная стра­ни­ца пред­став­ле­на на сай­те раз­ра­бот­чи­ка.

Уста­нов­ку сер­ви­са мож­но выпол­нить раз­ны­ми способами:

  • Из исход­ни­ков.
  • Как кон­тей­нер Docker (запус­ка­ет­ся docker-compose).
  • Tanka или Helm для раз­вер­ты­ва­ния в кла­сте­ре Kubernetes.
  • Вруч­ную, ска­чав бинар­ник и кон­фи­гу­ра­ци­он­ный файл (под­дер­жи­ва­ют­ся систе­мы на базе Linux и Windows).

По прин­ци­пу рабо­ты напо­ми­на­ет Prometheus — Loki исполь­зу­ет для сбо­ра мет­рик агент promtail и хра­нит дан­ные в TSDB базе (Time Series Data Base или база дан­ных вре­мен­ных рядов). Уста­нов­ку аген­та так­же мож­но выпол­нить раз­ны­ми сред­ства­ми — руч­ное копи­ро­ва­ние бинар­ни­ка, Docker, Helm chart, DaemonSet и Sidecar. Так­же систе­ма спо­соб­на соби­рать логи из кон­тей­не­ров Docker с помо­щью пла­ги­на Loki Docker Driver.

Сер­вис лег­ко инте­гри­ру­ет­ся с дру­ги­ми систе­ма­ми, напри­мер, Grafana (для визу­а­ли­за­ции в dashboard), Prometheus, Elasticsearch и дру­ги­ми. Важ­но отдель­но отме­тить спо­соб­ность Loki рабо­тать с потреб­ле­ни­ем мало­го коли­че­ства ресур­сов. Это воз­мож­но бла­го­да­ря индек­си­ро­ва­нию не всех дан­ных, а толь­ко тегов. Дан­ная идея поза­им­ство­ва­на у Prometheus.

Доку­мен­та­цию по Gragana Loki мож­но най­ти на сай­те Grafana Labs. Так­же на кана­ле Loki Slack мож­но задать вопрос и полу­чить поддержку.

 

В инструк­ции мы рас­смот­рим про­цесс уста­нов­ки и настрой­ки Grafana Loki в каче­стве сер­ве­ра сбо­ра логов. Есть несколь­ко спо­со­бов ее уста­нов­ки — Helm chart, в каче­стве кон­тей­не­ра Docker, ска­чать гото­вый бинар­ник или собрать его из исход­ни­ка. Мы выпол­ним уста­нов­ку из послед­не­го на систе­му Linux. Так­же, в каче­стве при­ме­ра, мы про­чи­та­ем лог веб-сер­ве­ра nginx и сде­ла­ем его вывод в Grafana.

Подготовка

Преж­де чем уста­нав­ли­вать Loki, под­го­то­вим наш сер­вер для работы.

Установка пакетов

Для загруз­ки исход­ни­ков нам пона­до­бить­ся загру­зить неко­то­рые фай­лы. Для это­го в систе­ме долж­ны быть уста­нов­ле­ны соот­вет­ству­ю­щие паке­ты. В зави­си­мо­сти от типа систе­мы про­цесс уста­нов­ки будет незна­чи­тель­но отличаться.

а) на систе­мах Red Hat:

yum install git wget

б) для систем на осно­ве Debian:

apt-get install git wget

Установка Go

Для ком­пи­ля­ции исход­ни­ка, нам необ­хо­ди­мо уста­но­вить Golang. Для это­го пере­хо­дим на стра­ни­цу загруз­ки и копи­ру­ем ссыл­ку на архив с его послед­ней версией:

Вос­поль­зо­вав­шись ссыл­кой, ска­чи­ва­ем архив на наш сервер:

wget https://golang.org/dl/go1.15.6.linux-amd64.tar.gz

* на момент напи­са­ния инструк­ции, послед­няя вер­сия была 1.15.6.

Рас­па­ко­вы­ва­ем архив в ката­лог /usr/local:

tar -v -C /usr/local -xzf go*.tar.gz

Откры­ва­ем файл:

vi /etc/profile

Добав­ля­ем в самый низ строку:

export PATH=$PATH:/usr/local/go/bin

Один раз выпол­ня­ем дан­ную команду:

export PATH=$PATH:/usr/local/go/bin

Про­ве­ря­ем, что go уста­нов­лен и готов выпол­нять команды:

go version

Мы долж­ны уви­деть вер­сию ска­чан­но­го пакета.

Настройка безопасности

1. Брандмауэр

В зави­си­мо­сти от исполь­зу­е­мо­го бранд­мау­э­ра, необ­хо­ди­мо выпол­нить сле­ду­ю­щие настройки.

а) если исполь­зу­ем iptables (по умол­ча­нию, в систе­мах на базе Debian):

iptables -I INPUT 1 -p tcp --dport 3100 -j ACCEPT

* дан­ная коман­да доба­вит пра­ви­ло на раз­ре­ше­ние пор­та 3100 (на кото­ром, по умол­ча­нию, запус­ка­ет­ся Grafana Loki).

Для сохра­не­ния пра­вил уста­нав­ли­ва­ем пакет:

apt-get install iptables-persistent

Сохра­не­ние пра­вил теперь мож­но выпол­нить командой:

netfilter-persistent save

б) если исполь­зу­ем firewalld (по умол­ча­нию, в систе­мах на базе Red Hat):

firewall-cmd --permanent --add-port=3100/tcp

firewall-cmd --reload

* дан­ная коман­да доба­вит пра­ви­ло на раз­ре­ше­ние пор­та 3100 (на кото­ром, по умол­ча­нию, запус­ка­ет­ся Grafana Loki).

2. SELinux

Как пра­ви­ло, в систе­мах на базе Red Hat акти­ви­ро­ва­на допол­ни­тель­ная систе­ма без­опас­но­сти. В нашей инструк­ции мы ее отклю­ча­ем командами:

setenforce 0

sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

* пер­вая коман­да вво­дит­ся до разо­во­го отклю­че­ния SELinux. Вто­рая не дает ему запу­стить­ся после перезагрузки.

Установка

Уста­нов­ка Grafana Loki сво­дит­ся к загруз­ке гото­во­го бинар­ни­ка или исход­ни­ка с после­ду­ю­щей ком­пи­ля­ци­ей. Так­же мы настро­им юнит в systemd для рабо­ты при­ло­же­ния в каче­стве сервиса.

Копирование бинарника и конфигурационного файла

Пере­хо­дим в каталог:

cd /usr/src/

Загру­жа­ем исход­ные фай­лы проекта:

git clone https://github.com/grafana/loki

Пере­хо­дим в ката­лог loki:

cd loki/

Запус­ка­ем ком­пи­ля­цию бинарника:

go build ./cmd/loki

В теку­щем ката­ло­ге появит­ся файл loki — пере­не­сем его в ката­лог /usr/local/bin:

mv loki /usr/local/bin/

Созда­дим каталог:

mkdir /etc/loki

… и пере­не­сем в него кон­фи­гу­ра­ци­он­ный файл:

mv cmd/loki/loki-local-config.yaml /etc/loki/

В кон­фи­ге, кото­рый идет в исход­ни­ке в каче­стве рабо­че­го ката­ло­га для Grafana Loki исполь­зу­ет­ся /tmp — мы это испра­вим дву­мя командами:

sed -i 's/\/tmp\/wal/\/opt\/loki\/wal/g' /etc/loki/loki-local-config.yaml

* пер­вой коман­дой мы меня­ем настрой­ку dir для wal (жур­на­ла предзаписи). 

sed -i 's/\/tmp\/loki/\/opt\/loki/g' /etc/loki/loki-local-config.yaml

* в дан­ном при­ме­ре мы заме­ни­ли путь для storage_configworking_directory и ruler storage на /opt/loki.

Созда­ем каталог:

mkdir /opt/loki

Выпол­ним пер­вый тесто­вый запуск сервиса:

/usr/local/bin/loki -config.file=/etc/loki/loki-local-config.yaml

Откры­ва­ем бра­у­зер и пере­хо­дим по адре­су http://192.168.0.15:3100/metrics, где 192.168.0.15 — IP-адрес наше­го сер­ве­ра Grafana Loki. Мы долж­ны уви­деть стра­ни­цу с метриками:

Зна­чит наш сер­вис запу­стил­ся и нор­маль­но рабо­та­ет. Мож­но пре­рвать его рабо­ту на сер­ве­ре ком­би­на­ци­ей кла­виш Ctrl + С и про­дол­жать настройку.

Автозапуск

Что­бы сер­вис мог авто­ма­ти­че­ски запус­кать­ся при стар­те систе­мы, доба­вим его в systemd.

Для нача­ла, созда­дим поль­зо­ва­те­ля, под кото­рым будет рабо­тать сервис:

useradd --no-create-home --shell /bin/false loki

* дан­ной коман­дой мы созда­дим поль­зо­ва­те­ля loki. Ему нель­зя будет вхо­дить в систе­му в каче­стве интер­ак­тив­но­го поль­зо­ва­те­ля, так­же для него не будет созда­на домаш­няя директория.

Дела­ем вла­дель­цем loki бинар­ник для запус­ка сервиса:

chown loki:loki /usr/local/bin/loki

Зада­ем вла­дель­ца для рабо­чих ката­ло­гов Loki:

chown -R loki:loki /etc/loki

chown -R loki:loki /opt/loki

Созда­ем юнит в systemd:

vi /etc/systemd/system/loki.service

Пере­чи­ты­ва­ем кон­фи­гу­ра­цию systemd:

systemctl daemon-reload

Теперь мож­но раз­ре­шить и стар­то­вать наш сервис:

systemctl enable loki --now

Про­ве­рить, что он запу­стил­ся и рабо­та­ет мож­но командой:

systemctl status loki

Уста­нов­ка сер­вер­ной части завершена.

Отправка логов на сервер

В нашем при­ме­ре мы пере­да­дим логи веб-сер­ве­ра NGINX в нашу Grafana Loki. Для это­го пере­хо­дим на сер­вер с NGINX и выпол­ним сле­ду­ю­щие действия.

Установка Promtail

Promtail — агент, кото­рый чита­ет и отправ­ля­ет логи на сер­вер. Его уста­нов­ка во мно­гом напо­ми­на­ет уста­нов­ку сер­ве­ра — полу­ча­ем бинар­ник и добав­ля­ем его в авто­за­груз­ку. В нашем при­ме­ре мы загру­зим уже ском­пи­ли­ро­ван­ный файл для запуска.

Для нача­ла, уста­но­вим сле­ду­ю­щие пакеты:

yum install unzip wget

unzip нужен для рас­па­ков­ки архи­ва с бинар­ни­ком; wget — для ска­чи­ва­ния архива.

Загру­жа­ем послед­нюю вер­сию promtail для Linux:

wget https://github.com/grafana/loki/releases/latest/download/promtail-linux-amd64.zip

* в нашем при­ме­ре загру­жа­ет­ся бинар­ник на систе­му 64-бит. На стра­ни­це https://github.com/grafana/loki/releases мож­но ска­чать фай­лы для уста­нов­ки под Linux и Windows.

Рас­па­ко­вы­ва­ем ска­чан­ный архив:

unzip promtail-linux-amd64.zip

Пере­но­сим бинар­ник в ката­лог /usr/local/bin:

mv promtail-linux-amd64 /usr/local/bin/promtail

* обра­ти­те вни­ма­ние, что мы его сра­зу пере­име­но­ва­ли в promtail.

Созда­ем ката­лог для кон­фи­гу­ра­ци­он­ных фай­лов promtail:

mkdir /etc/promtail

Созда­ем кон­фи­гу­ра­ци­он­ный файл:

vi /etc/promtail/promtail.yaml

* где 9080 — номер пор­та, на кото­ром будет слу­шать promtail; 192.168.0.15 — IP-адрес наше­го сер­ве­ра Loki, куда нуж­но отправ­лять данные.

Созда­ем юнит в systemd для promtail:

vi /etc/systemd/system/promtail.service

Пере­чи­ты­ва­ем кон­фи­гу­ра­цию systemd:

systemctl daemon-reload

Раз­ре­ша­ем запуск сер­ви­са promtail и стар­ту­ем его:

systemctl enable promtail --now

Про­ве­ря­ем статус:

systemctl status promtail

На кли­ен­те в настрой­ки бранд­мау­э­ра добав­ля­ем пра­ви­ло на раз­ре­ше­ние пор­та 9080.

а) если исполь­зу­ем iptables (Debian, Ubuntu):

iptables -I INPUT 1 -p tcp --dport 9080 -j ACCEPT

apt-get install iptables-persistent

netfilter-persistent save

б) если исполь­зу­ем firewalld (CentOS, Red Hat):

firewall-cmd --permanent --add-port=9080/tcp

firewall-cmd --reload

После уста­нов­ки promtail откры­ва­ем бра­у­зер и пере­хо­дим на стра­ни­цу http://192.168.0.25:9080/targets, где 192.168.0.25 — IP-адрес кли­ент­ско­го ком­пью­те­ра с NGINX. Мы долж­ны уви­деть страницу:

Promtail рабо­та­ет. Мож­но при­сту­пать к сбо­ру логов.

Настройка сбора логов

Откры­ва­ем кон­фи­гу­ра­ци­он­ный файл promtail:

vi /etc/promtail/promtail.yaml

… и добавляем:

* где:

  • job_name — имя зада­ния для чте­ния лога.
  • targets — ком­пью­тер, на кото­ром чита­ем лог.
  • job — мет­ка для име­ни зада­ния. Важ­ный пара­метр для выбор­ки данных.
  • __path__ — путь до фай­лов с логами.

Пере­за­пус­ка­ем сер­вис promtail:

systemctl restart promtail

Сно­ва захо­дим по адре­су http://192.168.0.25:9080/targets — мы долж­ны уви­деть настро­ен­ное нами задание:

Сбор логов настроен.

Настройка Grafana

Пере­хо­дим к сер­ве­ру с Grafana. Он может быть уста­нов­лен на отдель­ном сер­ве­ре или на том же сер­ве­ре с Loki.

Захо­дим в веб-интер­фейс и пере­хо­дим в Configuration - Data Sources:

Добав­ля­ем новый источ­ник, кли­кая по Add data source:

Сре­ди спис­ка воз­мож­ных источ­ни­ков выби­ра­ем Loki:

В настрой­ках зада­ем имя и ука­зы­ва­ем IP-адрес сер­ве­ра Loki:

* в нашем при­ме­ре зада­ет­ся имя Loki и под­клю­че­ние к сер­ве­ру 192.168.0.15.

Нажи­ма­ем на Save & Test:

Если мы уви­де­ли сооб­ще­ние «Data source connected and labels found.»:

… зна­чит под­клю­че­ние выпол­не­но и мож­но дви­гать­ся дальше.

Пере­хо­дим в раз­дел Create - Dashboard:

Кли­ка­ем по кноп­ке Add new panel:

В открыв­шем­ся окне выби­ра­ем в каче­стве источ­ни­ка дан­ных Loki, затем кли­ка­ем по Log labels - выби­ра­ем job и nginxlogs:

Мы уви­дим Unable to graph data (так как логи пред­став­ля­ют из себя дан­ные, на осно­ве кото­рых нель­зя посто­ить гра­фик) — кли­ка­ем по Switch to table view:

Мы долж­ны уви­деть стро­ки из логов: 

Логи NGINX отоб­ра­жа­ют­ся в Grafana.

Парсинг лога

Мы уви­де­ли логи в гра­фане, но они пред­став­лен­ны в неудоб­ном для отбо­ра и филь­ра­ции виде. Попро­бу­ем это испра­вить с помо­щью пар­син­га логов на сто­роне promtail.

Откры­ва­ем файл для редактирования:

vi /etc/promtail/promtail.yaml

Допол­ним нашу зада­чу для сбо­ра логов NGINX:

* обра­ти­те вни­ма­ние, что к име­ю­щей­ся настрой­ки мы доба­ви­ли pipeline_stages:

  • selector — тег для отбо­ра логов, кото­рые нуж­но парсить.
  • expression — регу­ляр­ное выра­же­ние для пар­син­га логов. 
  • labels — спи­сок тегов, кото­рые мы будем пере­да­вать в loki. Обра­ти­те вни­ма­ние, что назва­ния дан­ных тегов соот­вет­ствую назва­ни­ям, кото­рые мы зада­ли в expression.

Пере­за­пус­ка­ем сер­вис для promtail:

systemctl restart promtail

Идем в Grafana — в Log labels мы долж­ны уви­деть новые кри­те­рии для филь­тра по тегам:

Про­бу­ем доба­вить, напри­мер, фильтр по ста­ту­су отве­та веб-сервера: