ФАЙЛИ В /var/log/netpulse. rsyslog читає journald і розкладає по файлах
на службу. Драйвер docker лишається journald, а не syslog: syslog
віддав би рядки назовні й нічого не лишив докеру, тож `docker logs`
замовк би назавжди — і мовчання виглядало б як «служба нічого не пише».
Тепер працюють усі три шляхи: docker logs, journalctl, файли.
Дорогою три власні помилки, кожна виглядала як «rsyslog не працює»:
1. Умова матчила $!CONTAINER_NAME — метадані журналу. journalctl їх
бачить, а до правил rsyslog вони доходять не завжди. Каталог
створювався й лишався порожнім.
2. Тег «netpulse/{{.Name}}» здавався охайнішим, але rsyslog обриває
programname на скісній: для ВСІХ контейнерів вона ставала просто
«netpulse». Тег тепер — саме ім'я контейнера, воно й так має
префікс проєкту.
3. Шаблон `%msg:::sp-if-no-1st-sp,drop-last-lf%` давав ПОРОЖНІЙ
текст: файли були, рядки були, слів не було. Журнал виглядав
робочим і не містив нічого — найгірший різновид поломки.
Конфігурації в deploy/, щоб їхали клієнтам, а не лишались разовим
налаштуванням одного сервера.
МІНІКАРТА. Штрих рядка був 2 px при 3 px на рядок — просвіт в один
піксель. На дробовому масштабі екрана (1.25, 1.5 — тобто на більшості
ноутбуків) він губився при округленні, і рядки злипались у суцільну
пляму: мінікарта показувала не форму конфігу, а сірий прямокутник.
Тепер штрих 1 px, просвіт удвічі товщий за нього й переживає будь-яке
округлення. Малюнок став блідішим — це правильний бік розміну: на
мінікарту дивляться, щоб побачити структуру, а не прочитати текст.
74 lines
5 KiB
Text
74 lines
5 KiB
Text
# Журнали NetPulse звичайними файлами в /var/log/netpulse/.
|
||
#
|
||
# Ставиться в /etc/rsyslog.d/30-netpulse.conf
|
||
# Разом із deploy/logrotate-netpulse і накладкою
|
||
# deploy/docker-compose.journald.yml.
|
||
#
|
||
# ЧОМУ ЧИТАЄМО ЖУРНАЛ, А НЕ ПЕРЕХОПЛЮЄМО ПОТІК
|
||
#
|
||
# Очевидний шлях — драйвер `syslog` у докера: він шле рядки просто в
|
||
# rsyslog. Але тоді докер їх у себе НЕ КЛАДЕ, і `docker logs` замовкає
|
||
# назавжди. Людина, яка про це не знає, робить із мовчання висновок
|
||
# «служба нічого не пише» — а це найгірший різновид помилки, бо він
|
||
# виглядає як факт.
|
||
#
|
||
# Тому драйвер лишається journald, а rsyslog читає вже записане
|
||
# (imjournal). Обидва шляхи працюють одночасно: `docker logs`, journalctl
|
||
# і файли показують те саме.
|
||
#
|
||
# Ціна: рядок лежить у двох місцях — у журналі systemd і у файлі. На
|
||
# стелі 1 ГБ у journald і ротації нижче це десятки мегабайтів, тобто
|
||
# дешевше за годину пошуку причини без журналу.
|
||
|
||
module(load="imjournal" StateFile="imjournal-netpulse.state" Ratelimit.Interval="0")
|
||
|
||
# Розбираємо ТЕГ, а не метадані журналу.
|
||
#
|
||
# Перша спроба матчила $!CONTAINER_NAME — поле, яке journald справді
|
||
# кладе (journalctl його бачить), але до правил rsyslog воно доходить
|
||
# не завжди: залежить від того, чи прийшов рядок через imjournal, чи
|
||
# через imuxsock, куди journald форвардить syslog. Каталог у нас
|
||
# створився, правило не спрацювало жодного разу, і зовні це виглядало
|
||
# як «rsyslog не працює» — хоча він працював, просто умова не збігалась.
|
||
#
|
||
# Тег `netpulse/<ім'я>` ми задаємо самі в накладці journald, і він
|
||
# приїжджає звичайним syslog-тегом обома шляхами. Тобто умова тепер
|
||
# спирається на те, що ми контролюємо, а не на те, що може не доїхати.
|
||
#
|
||
# `:10:$` бере тегу з десятого символу до кінця — рівно те, що після
|
||
# `netpulse/`.
|
||
template(name="netpulseLogFile" type="string"
|
||
string="/var/log/netpulse/%programname%.log")
|
||
|
||
# Формат: час у ISO, ім'я служби, саме повідомлення.
|
||
#
|
||
# %msg% без опцій навмисно. Спершу стояло
|
||
# `%msg:::sp-if-no-1st-sp,drop-last-lf%` — і воно давало ПОРОЖНІЙ текст:
|
||
# файли з'являлись, рядки в них були, але після імені служби не було
|
||
# нічого. Тобто журнал виглядав робочим і не містив жодного слова —
|
||
# найгірший різновид поломки. Пробіл між назвою й текстом ставимо
|
||
# самі: journald його не лишає, і без нього рядок злипається в
|
||
# «netpulse-api-1{"time":...» — читабельно для jq, але не для ока.
|
||
#
|
||
# Повідомлення в NetPulse — уже JSON від slog, тож обгортати його ще
|
||
# однією структурою не треба: `jq` має отримати рядок, який він уміє
|
||
# прочитати. Час і служба стоять ПЕРЕД ним, щоб `tail` лишався
|
||
# читабельним для людини, а `cut -d" " -f3-` віддавав чистий JSON.
|
||
template(name="netpulseLine" type="string"
|
||
string="%timereported:::date-rfc3339% %programname% %msg%\n")
|
||
|
||
# Умова — на ІМЕНІ КОНТЕЙНЕРА, яке докер кладе тегом (див. накладку
|
||
# deploy/docker-compose.journald.yml). Метадані журналу ($!CONTAINER_NAME)
|
||
# для цього не годяться: до правил rsyslog вони доходять не завжди, і
|
||
# перша спроба на них мовчки не спрацювала.
|
||
if ($programname startswith "netpulse-") then {
|
||
action(type="omfile"
|
||
dynaFile="netpulseLogFile"
|
||
template="netpulseLine"
|
||
dirCreateMode="0750"
|
||
fileCreateMode="0640"
|
||
dynaFileCacheSize="20")
|
||
# stop, щоб ті самі рядки не поїхали ще й у /var/log/syslog: там
|
||
# вони перемішаються з усім іншим на машині, а користі не додадуть.
|
||
stop
|
||
}
|