Содержание

Что такое лог (log) программы.

Решая различные компьютерные задачи, можно не раз столкнуться с таким понятием как лог (с англ. log). Лог какой-то программы. Давайте попробуем разобраться что это такое и для чего это нужно. 

Log (с англ. журнал). У большинства программ, которые установлены на вашем компьютере, есть этот самый журнал. 

Журнал — это специальный текстовый файл, в который программа может вносить какие-то записи. 

Т.е. это такой же обычный файл, который мы с вами можем создать на компьютере. Таким же образом программа работая на компьютере, может создать этот файл и вносить туда программным образом какие-то текстовые пометки.

Зачем же программе вести какие-то записи, какой-то журнал?

Дело в том, что если мы с вами будем следить за человеком, который работает на компьютере, мы можем сказать, что этот человек делал в конкретный момент времени, какие программы он запускал, какие ошибки он совершал при работе на компьютере и.т.д.

Но, если мы говорим о компьютерной программе, здесь все не так ясно. Все действия, которые производит программа, они скрыты от взгляда обычного пользователя. Они обычно происходят с такой большой скоростью событий, что человеческий глаз просто не успеет за все этим уследить.

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

Лог файлов для программы может быть несколько. В зависимости от назначения может быть так называемый access_log — это журнал, где фиксируются все взаимодействия пользователей с этой программой, что они делали и.т.д.

В лог файле может множество записей. Каждая текстовая строка — это одно взаимодействие с программой.

В каждой записи содержится информация о том, что происходило с программой и когда это происходило.

Также можно часто встретить так называемый error_log — это лог тех ошибок, которые возникали при работе с программой. В этом логе можно увидеть код ошибки, которая произошла в программе, когда эта ошибка произошла, каким пользователем операционной системы эта ошибка была вызвана и.т.д.

 Давайте подведем итог, что такое лог и зачем он нужен. Это текстовый файл, в который программа записывает какие-то события, которые с ней происходят. Благодаря этим событиям мы можем получить какую-то дополнительную информацию, что происходило с этой программой в какой-то определенный момент времени, получить отладочную информацию, чтобы легче устранить какую-то ошибку. 

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

Лог — это первоисточник, в который нужно заглядывать если ваша программа работает с каким-то ошибками и не так, как нужно. 

Надеюсь, что стало понятнее что такое лог-файл и зачем он нужен и вы теперь будете использовать этот журнал в своей работе. 

лог — Викисловарь

Морфологические и синтаксические свойства[править]

лог

Существительное, неодушевлённое, мужской род, 2-е склонение (тип склонения 3a по классификации А. А. Зализняка).

Встречается также вариант склонения по схеме 3c①: лога́, лого́в, лога́м, лога́ми, лога́х.

Имеет омоформу логов с сущ. логово.

Корень: -лог-.

Произношение[править]

  • МФА (3a): ед. ч. [ɫok], мн. ч. [ˈɫoɡʲɪ]
  • МФА (3c①): ед. ч. [ɫok], мн. ч. [ɫɐˈɡa]

Семантические свойства[править]

Значение[править]
  1. редк. широкий, значительной длины овраг с отлогими склонами ◆ Там те же белые холмы убежали прочь, волнуясь вдали беспорядочными логами, лесистыми балками и тёмными, зияющими оврагами. Г. П. Данилевский, «Воля», 1863 г. (цитата из Национального корпуса русского языка, см. Список литературы) ◆ Живая горная вода сочилась из-под каждой горы, катилась по логам и уклонам, сливалась в бойкие речки, проходила через озёра и, повернув тысячи тяжёлых заводских и мельничных колёс, вырывалась, наконец, на степной простор .. Д. Н. Мамин-Сибиряк, «Три конца», 1890 г. (цитата из Национального корпуса русского языка, см. Список литературы) ◆ Я полюбил оазис ваш дубовый, // В кольце лого́в, средь пашни чернозёмной, // С усадьбою в тиши его укромной, // Где ввечеру пустынно кличут совы.
    В. И. Иванов, «„Я полюбил оазис ваш дубовый…“», 1914 г. (цитата из Национального корпуса русского языка, см. Список литературы)
    ◆ Восточный и западный склоны круто падали в лога́. А. В. Иванов, «Сердце Пармы», 2000 г. (цитата из Национального корпуса русского языка, см. Список литературы)
Синонимы[править]
  1. балка II, логовина; частичн.: распадок, ложбина, суходол, буерак, яр, яруга
Антонимы[править]
  1. возвышенность, холм, гряда
Гиперонимы[править]
  1. овраг, низина, ложбина, низменность
Гипонимы[править]

Родственные слова[править]

Список всех слов с корнем «лаг-/лог-/лаж-/лож-/леж-/лёж-/лег-/лёг-/леч-» [править]
  • имена собственные: Лажечников
  • пр.  существительные: благорасположение, благорасположенье, бумаголожество, влагалище, вложение, вложенность, вложенье, залегание, залеганье, залог, заложение, заложенность, заложенье, заложник, заложница, изложение, изложенье, изложница, лежак, лежанка, лежбище, лежебока, лёжка, лог, логовина, логовинка, логовище, логово, ложе, ложок, мужеложество, мужеложец, мужеложник, мужеложство, налегание, налеганье, налог, налоговик, налогообложение, налогообложенье, наложение, наложенье, наложник, наложница, низложение, низложенье, обложение, обложенность, обложенье, основоположник, основоположница, отложение, отложенье, перелёживание, переложение, переложенье, подлежащее, подлог, подложка, полагание, полаганье, положение, положенье, положеньице, положительность, послелог, предлежание, предлежанье, предлог, предложение, предложенье, предположение, предположенье, прилежание, прилежанье, приложение, приложенье, продналог, пролежень, пролёживание, разложение, разложенье, расположение, расположенность, расположенье, рукоположение, рукоположенье, слёживание, слёживанье, сложение, сложенье, соложество, соложник, соложница, спецпредложение, спецпредложенье, телосложение, телосложенье, уложение, уложенность, уложенье, целеполагание, целеполаганье
  • прилагательные: антислёживающий, влагалищный, залежалый, залоговый, лежалый, лежаночный, лежбищный, мужеложеский, налоговый, неположенный, непреложный, неслаженный, несложенный, несложный, обложной, основополагающий, отложной, подлежащий, подложный, полагающий, полагающийся, положенный, положительный, предложный, предположительный, прилежащий, пролежневый, располагающий, слаженный, сложенный, сложный, сослагательный
  • глаголы: влагать, влагаться, вложить, вложиться, возлагать, возлегать, возлечь, возложить, вылежать, вылечь, выложить, выложиться, долежать, долежаться, доложить, доложиться, залагать, залагаться, залегать, залегаться, заложить, заложиться, излагать, излагаться, изложить, изложиться, лежать, лечь, ложить, ложиться, мужеложествовать, надлежать, налагать, налагаться, налегать, налегаться, налечь, наложить, наложиться, низлагать, низложить, облагать, облагаться, облегать, облегаться, облечь, облечься, обложить, обложиться, отлагать, отлагаться, отлегать, отлежать, отлежаться, отлечь, отложить, отложиться, передоложить, перезаложить, перезаложиться, перелагать, перелагаться, перелегать, перележать, перелёживать, перелечь, переложить, переложиться, подлагать, подлагаться, подлегать, подлежать, подлечь, подложить, подложиться, полагать, полагаться, полегать, полежать, полёживать, полечь, положить, положиться, предлагать, предлагаться, предлежать, предложить, предложиться, предполагать, предполагаться, предположить, предположиться, предрасполагать, предрасположить, прилагать, прилагаться, прилегать, прилежать, прилечь, приложить, приложиться, принадлежать, пролагать, пролагаться, пролегать, пролежать, пролежаться, пролёживать, пролёживаться, пролечь, проложить, проложиться, противополагать, противоположить, разлагать, разлагаться, разлечь, разлечься, разложить, разложиться, располагать, располагаться, расположить, расположиться, рукополагать, рукоположить, слагать, слагаться, слегать, слежаться, слёживать, слёживаться, слечь, слечься, сложить, сложиться, соложествовать, сослагать, улежать, улежаться, улёживаться, улечься, уложить, уложиться
  • наречия: лажно, лёжа, положено, положительно, предположительно, сложно

Этимология[править]

Происходит от лежать, далее от праслав. *lеžаti, от кот. в числе прочего произошли: русск. лог, логово, влог «углубление, яма»,

зало́г — также в знач. «поле под паром», проло́г «долина», перело́г «пар (поле)», изло́г «овраг», укр. лігво, болг. лог «приманка», сербск. ло̑г (род. п. ло̏га) «лежание». Ср. лит. atlagaĩ «поле, долго лежавшее под паром», греч. λόχος «засада», галльск. logan, вин. ед. «могила». Использованы данные словаря М. Фасмера. См. Список литературы.

Фразеологизмы и устойчивые сочетания[править]

Перевод[править]

Анаграммы[править]

Библиография[править]

Морфологические и синтаксические свойства[править]

лог

Существительное, неодушевлённое, мужской род, 2-е склонение (тип склонения 3a по классификации А. А. Зализняка).

Корень: -лог-.

Произношение[править]

  • МФА: ед. ч. [ɫok], мн. ч. [ˈɫoɡʲɪ]

Семантические свойства[править]

Значение[править]
  1. неол., комп. автоматически создаваемый хронологический протокол работы программы или устройства ◆ Нужна регистрация, чтоб не вылавливать каждого хулигана по серверным логам. «Книга жалоб и предложений», 2004–2006 гг. (цитата из Национального корпуса русского языка, см. Список литературы)
Синонимы[править]
Антонимы[править]
Гиперонимы[править]
  1. протокол, журнал
Гипонимы[править]
  1. протолог

Родственные слова[править]

Этимология[править]

Заимствовано из англ. log ‘протокол, журнал; судовой журнал’ (в совр. значении с 1913, в оригинальном — с 1840-х), матросского сокращения от logbook ‘судовой журнал’ (с 1670-х), от log ‘бревно; лаг’ (каковое русское слово из того же источника), поскольку выбрасываемое за борт бревно-лаг в XVII—XVIII вв. играло ключевую роль в измерении пройденного судном за день расстояния, которое было основным содержимым журнала, от ср.-англ. logge, log (с XIV в.), от неустановленной формы.

Фразеологизмы и устойчивые сочетания[править]

Перевод[править]

Библиография[править]

туториал по системным логам Linux

Логи (журнал сервера, англ. server log) – это записываемые фрагменты данных, описывающие то, что в конкретный момент времени делает сервер, ядро, службы и приложения. Вот пример лога SSH из /var/log/auth.log:

        May 5 08:57:27 ubuntu-bionic sshd[5544]: pam_unix(sshd:session): session opened for user vagrant by (uid=0)

Обратите внимание, что непосредственно перед сообщением лог содержит несколько полей: метка времени, имя хоста, инициатор события и идентификатор процесса.

Логи в Linux поступают из разных источников. Ниже перечислены основные.

Подсистема systemd. Большинство дистрибутивов Linux для управления службами имеют в своём составе systemd. Подсистема инициализации и управления ловит выходные данные служб и записывает их в журнал. Для работы с логами systemd используется система журналирования journalctl (шпаргалка по работе с journalctl):

        $ journalctl
...
May 05 08:57:27 ubuntu-bionic sshd[5544]: pam_unix(sshd:session): session opened for user vagrant by (uid=0)
...
    

Сообщения процессов по стандарту syslog. При отсутствии systemd такие процессы, как SSH, могут записывать данные в UNIX-сокет в формате syslog. Демон syslog, например, rsyslog, выбирает сообщение, анализирует и по умолчанию записывает его в /var/log.

Ядро Linux пишет собственные логи в особый буфер. Подсистемы systemd или syslog могут считывать журналы из этого буфера, а затем записывать их в свои журналы или файлы – обычно /var/log/kern.log. Чтобы посмотреть логи ядра, воспользуйтесь dmesg:

        $ dmesg -T
...
[Tue May 5 08:41:31 2020] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null)
...
    

Audit logs. Особый случай сообщений ядра, предназначенных для аудита событий, таких как доступ к файлам. Обычно для прослушивания таких журналов безопасности, существует специальная служба, например, auditd, записывающая свои сообщения в /var/log/audit/audit.log.

Журнал приложений. Несистемные приложения имеют тенденцию записывать данные в /var/log:

  • Apache (httpd) обычно пишет в /var/log/httpd или /var/log/apache2. Журналы HTTP-доступа находятся в файле /var/log/httpd/access.log.
  • Логи MySQL обычно находятся в /var/log/mysql.log или /var/log/mysqld.log.
  • Старые версии Linux могут записывать свои логи загрузки с помощью bootlogd в /var/log/boot или /var/log/boot.log. В современных ОС об этом заботится systemd: вы можете просматривать связанные с загрузкой журналы с помощью journalctl -b. Дистрибутивы без systemd снабжены syslog-демоном, считывающим данные из буфера ядра. Таким образом, вы можете найти свои boot/reboot-журналы в /var/log/messages или /var/log/syslog.

Как правило, вы найдете журналы пингвиньего сервера в каталоге /var/log и подкаталогах. Это место, где syslog-демонам даны полные права на запись. Также это то место, которое у большинства приложений (например, Apache) указано по умолчанию, как место хранения логов.

Для systemd расположение по умолчанию – /var/log/journal, но просматривать файлы логов напрямую не получится – они хранятся в двоичном формате. Как же быть?

Если ваш дистрибутив Linux использует Systemd (как и большинство современных дистрибутивов), то все ваши системные журналы находятся в специальной области journal. Просмотреть их можно с помощью journalctl (наиболее важные команды journalctl).

Если ваш дистрибутив использует syslog, для их просмотра используются стандартные инструменты: cat, less или grep:

        # grep "error" /var/log/syslog | tail
Mar 31 09:48:02 ubuntu-bionic rsyslogd: unexpected GnuTLS error -53 - this could be caused by a broken connection. GnuTLS reports: Error in the push function. [v8.2002.0 try https://www.rsyslog.com/e/2078 ]
...
    

Если для управления журналами вы используете auditd, всё найдётся в файле /var/log/audit.log. В поиске и анализе поможет ausearch.

Заметим, что хорошим тоном является хранение всех логов централизованно, в одном месте. Особенно если у вас несколько серверов. Обсудим эту задачу подробнее.

Системные журналы могут находиться в двух местах: в systemd или в обычных текстовых файлах, записанных демоном syslog. В некоторых дистрибутивах, например, Ubuntu, есть и то, и другое: journald настроен на пересылку в syslog. Это осуществляется путем установки ForwardToSyslog=Yes в конфиге journald.conf.

Централизация журналов с помощью Journald

Если в ваш дистрибутив включён systemd, для централизации журналов мы рекомендуем использовать journal-upload.

Централизация журналов с помощью syslog

Существует несколько случаев, в которых подойдет централизация с применением syslog:

  • Если в ваш дистрибутив не включён journald. Это означает, что системные журналы направляются непосредственно в syslog-демон.
  • Когда необходимо собирать и анализировать журналы приложений. Например, в случае с журналами для Apache через rsyslog и Elasticsearch.
  • Если вы хотите перенаправить записи – ForwardToSyslog=Yes. Для этого в качестве транспорта следует использовать syslog-протокол. Однако подход приведет к потере некоторых структурированных данных journald т. к. он пересылает только поля syslog-specific.
  • Когда вы настроили syslog-демон для чтения из журналов (как это делает journalctl). Такой подход не приводит к потере структурированных данных, но более чувствителен к ошибкам (например, в случае повреждения журнала) и увеличивает накладные расходы.

Во всех перечисленных ситуациях информация будут проходить через демон syslog, а оттуда их можно отправить в любое место и использовать на своё усмотрение.

Большинство дистрибутивов Linux поставляются с rsyslog. Чтобы пересылать данные на другой сервер через TCP, добавьте следующую строку в /etc/rsyslog.conf:

        *.* @@logsene-syslog-receiver.example.com
    

Эта строка будет заворачивать данные на сервер example.com. Вы можете заменить logsene-syslog-receiver.[…..] именем своего syslog-хоста.

Некоторые демоны могут выводить данные в Elasticsearch через HTTP/HTTPS. Одним из них является наш rsyslog. Например, если вы юзаете rsyslog на Ubuntu, сначала установите модуль Elasticsearch:

        sudo apt-get install rsyslog-elasticsearch
    

Затем в конфигурационном файле вам потребуется поправить два элемента: шаблон JSON для Elasticsearch:

        template(name="LogseneFormat" type="list" option.json="on") {
 constant(value="{")
 constant(value="\"@timestamp\":\"")
 property(name="timereported" dateFormat="rfc3339")
 constant(value="\",\"message\":\"")
 property(name="msg")
 constant(value="\",\"host\":\"")
 property(name="hostname")
 constant(value="\",\"severity\":\"")
 property(name="syslogseverity-text")
 constant(value="\",\"facility\":\"")
 property(name="syslogfacility-text")
 constant(value="\",\"syslog-tag\":\"")
 property(name="syslogtag")
 constant(value="\",\"source\":\"")
 property(name="programname")
 constant(value="\"}")
}
    

и action, который пересылает данные в Elasticsearch, используя указанный выше шаблон:

        module(load="omelasticsearch")
action(type="omelasticsearch"
 template="LogseneFormat" # шаблон,объявленный ранее
 searchIndex="LOGSENE_APP_TOKEN_GOES_HERE"
 server="logsene-receiver.example.com"
 serverport="443"
 usehttps="on"
 bulkmode="on"
 queue.dequeuebatchsize="100" # сколько сообщений отправлять за раз
 action.resumeretrycount="-1") # буфер сообщений
    

В приведенном примере показано, как отправлять сообщения в API Elasticsearch на example.com. Настройте action на ваш локальный Elasticsearch:

  • searchIndex – будет вашим алиасом;
  • server – имя хоста (ноды) Elasticsearch;
  • serverport может быть 9200 или кастомным, главное, чтобы на нем слушал Elasticsearch;
  • usehttps= "off" – отправление данных по http.

Независимо от того, используете ли вы syslog-протокол или что-то еще, лучше перенаправлять данные непосредственно из демона, чем искать проблемы в отдельных файлах из /var/log.

Это не значит, что файлы в /var/log бесполезны. Они пригодятся в следующих случаях:

  • приложения пишут туда свои логи, например, HTTP, FTP, MySQL и т. д.,
  • требуется обработать системные журналы, например, с помощью grep.

Здесь мы рассмотрим ключевые файлы логов, какую информацию они хранят, как настраивается rsyslog для записи и как посмотреть информацию с помощью journalctl.

Журнал /var/log/syslog или /var/log/messages

Это «всеохватывающий» системный лог:

        # logger "this is a test"
# tail -1 /var/log/syslog
May 7 15:33:11 ubuntu-bionic test-user: this is a test
    

Вы найдёте здесь все сообщения: ошибки, информационные сообщения и все другие серьёзности. Исключением является stop action.

Если в /var/log/syslog или /var/log/messages пусто, скорее всего, journald не перенаправляет данные в syslog. Все те же данные можно просмотреть, вызвав journalctl без параметров.

        # journalctl --no-pager | grep "this is a test"
May 07 15:33:11 ubuntu-bionic test-user[7526]: this is a test
    

Журналы /var/log/kern.log или /var/log/dmesg

Сюда по умолчанию отправляются сообщения ядра:

        Apr 17 16:47:28 ubuntu-bionic kernel: [ 0.004000] console [tty1] enabled
    

И снова, если у вас нет syslog (или файл пустой/отсутствует) – используйте journalctl:

        kern.* /var/log/kern.log
    

Журналы /var/log/auth.log или /var/log/secure

Здесь вы найдете сообщения об аутентификации, генерируемые такими службами, как sshd:

        May 7 15:03:09 ubuntu-bionic sshd[1202]: pam_unix(sshd:session): session closed for user vagrant
    

Вот ещё один фильтр по значениям auth и authpriv:

        auth,authpriv.* /var/log/auth.log
    

Вы можете использовать такие фильтры в journalctl, используя числовые уровни объектов:

        # journalctl SYSLOG_FACILITY=4 SYSLOG_FACILITY=10
...
May 7 15:03:09 ubuntu-bionic sshd[1202]: pam_unix(sshd:session): session closed for user vagrant
...
    

Журнал /var/log/cron.log

Сюда отправляются ваши cron-сообщения (jobs-ы, выполняемые регулярно):

        May 06 08:19:01 localhost.localdomain anacron[1142]: Job `cron.daily' started
    

Пример фильтра:

        cron.* /var/log/cron
    

С journalctl можно сделать так:

        # journalctl SYSLOG_FACILITY=9
    

Журнал /var/log/mail.log или /var/log/maillog

Практически все демоны (такие как Postfix, cron и т. д.) обычно пишут свои логи в syslog. Затем rsyslog раскладывает эти логи по файлам:

        mail.* /var/log/mail.log
    

С помощью journald просматривать журналы можно так:

        # journalctl SYSLOG_FACILITY=2
    
  • Расположение и формат системных журналов Linux зависят от того, как настроен дистрибутив.
  • Большинство дистрибутивов имеют systemd, и все логи «живут» там. Чтобы что-то просмотреть и найти, используйте journalctl.
  • Некоторые дистрибутивы передают системные журналы в syslog, либо напрямую, либо через journal. В этом случае у вас, скорее всего, есть логи, записанные в отдельные файлы в /var/log.
  • Если вы управляете несколькими серверами, вам потребуется централизовать журналирование с помощью специального ПО или использовать собственный ELK-стек.

Логгирование событий невероятно важная и серьёзная штука в любой сфере администрирования и ОС. Рекомендуем отнестись ответственно к данной теме – она будет полезна при дебагинге, разработке и просто в управлении инфраструктурой.

«Помедленнее, я записываю»: туториал по системным логам Linux

Из этой статьи вы узнаете, что такое журналы Linux, какие инструменты их генерируют и где эти журналы хранятся, — пишет proglib.io. — Рассмотрим, как и зачем искать и читать результаты journald и syslog, а также о том, как собрать логи нескольких серверов в одном месте.

Что такое логи?

Логи (журнал сервера, англ. server log) – это записываемые фрагменты данных, описывающие то, что в конкретный момент времени делает сервер, ядро, службы и приложения. Вот пример лога SSH из /var/log/auth.log:

May 5 08:57:27 ubuntu-bionic sshd[5544]: pam_unix(sshd:session): session opened for user vagrant by (uid=0)

Обратите внимание, что непосредственно перед сообщением лог содержит несколько полей: метка времени, имя хоста, инициатор события и идентификатор процесса.

Логи в Linux поступают из разных источников. Ниже перечислены основные.

Подсистема systemd. Большинство дистрибутивов Linux для управления службами имеют в своём составе systemd. Подсистема инициализации и управления ловит выходные данные служб и записывает их в журнал. Для работы с логами systemd используется система журналирования journalctl (шпаргалка по работе с journalctl):

$ journalctl
...
May 05 08:57:27 ubuntu-bionic sshd[5544]: pam_unix(sshd:session): session opened for user vagrant by (uid=0)
...

Сообщения процессов по стандарту syslog. При отсутствии systemd такие процессы, как SSH, могут записывать данные в UNIX-сокет в формате syslog. Демон syslog, например, rsyslog, выбирает сообщение, анализирует и по умолчанию записывает его в /var/log.

Ядро Linux пишет собственные логи в особый буфер. Подсистемы systemd или syslog могут считывать журналы из этого буфера, а затем записывать их в свои журналы или файлы – обычно /var/log/kern.log. Чтобы посмотреть логи ядра, воспользуйтесь dmesg:

$ dmesg -T
...
[Tue May 5 08:41:31 2020] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null)
...

Audit logs. Особый случай сообщений ядра, предназначенных для аудита событий, таких как доступ к файлам. Обычно для прослушивания таких журналов безопасности, существует специальная служба, например, auditd, записывающая свои сообщения в /var/log/audit/audit.log.

Журнал приложений. Несистемные приложения имеют тенденцию записывать данные в /var/log:

  • Apache (httpd) обычно пишет в /var/log/httpd или /var/log/apache2. Журналы HTTP-доступа находятся в файле /var/log/httpd/access.log.
  • Логи MySQL обычно находятся в /var/log/mysql.log или /var/log/mysqld.log.
  • Старые версии Linux могут записывать свои логи загрузки с помощью bootlogd в /var/log/boot или /var/log/boot.log. В современных ОС об этом заботится systemd: вы можете просматривать связанные с загрузкой журналы с помощью journalctl -b. Дистрибутивы без systemd снабжены syslog-демоном, считывающим данные из буфера ядра. Таким образом, вы можете найти свои boot/reboot-журналы в /var/log/messages или /var/log/syslog.

Если коротко: где искать логи?

Как правило, вы найдете журналы пингвиньего сервера в каталоге /var/log и подкаталогах. Это место, где syslog-демонам даны полные права на запись. Также это то место, которое у большинства приложений (например, Apache) указано по умолчанию, как место хранения логов.

Для systemd расположение по умолчанию – /var/log/journal, но просматривать файлы логов напрямую не получится – они хранятся в двоичном формате. Как же быть?

Как анализировать журналы

Если ваш дистрибутив Linux использует Systemd (как и большинство современных дистрибутивов), то все ваши системные журналы находятся в специальной области journal. Просмотреть их можно с помощью journalctl (наиболее важные команды journalctl).

Если ваш дистрибутив использует syslog, для их просмотра используются стандартные инструменты: cat, less или grep:

# grep "error" /var/log/syslog | tail
Mar 31 09:48:02 ubuntu-bionic rsyslogd: unexpected GnuTLS error -53 - this could be caused by a broken connection. GnuTLS reports: Error in the push function. [v8.2002.0 try https://www.rsyslog.com/e/2078 ]
...

Если для управления журналами вы используете auditd, всё найдётся в файле /var/log/audit.log. В поиске и анализе поможет ausearch.

Заметим, что хорошим тоном является хранение всех логов централизованно, в одном месте. Особенно если у вас несколько серверов. Обсудим эту задачу подробнее.

Централизация логов в Linux

Системные журналы могут находиться в двух местах: в systemd или в обычных текстовых файлах, записанных демоном syslog. В некоторых дистрибутивах, например, Ubuntu, есть и то, и другое: journald настроен на пересылку в syslog. Это осуществляется путем установки ForwardToSyslog=Yes в конфиге journald.conf.

Централизация журналов с помощью Journald

Если в ваш дистрибутив включён systemd, для централизации журналов мы рекомендуем использовать journal-upload.

Централизация журналов с помощью syslog

Существует несколько случаев, в которых подойдет централизация с применением syslog:

  • Если в ваш дистрибутив не включён journald. Это означает, что системные журналы направляются непосредственно в syslog-демон.
  • Когда необходимо собирать и анализировать журналы приложений. Например, в случае с журналами для Apache через rsyslog и Elasticsearch.
  • Если вы хотите перенаправить записи – ForwardToSyslog=Yes. Для этого в качестве транспорта следует использовать syslog-протокол. Однако подход приведет к потере некоторых структурированных данных journald т. к. он пересылает только поля syslog-specific.
  • Когда вы настроили syslog-демон для чтения из журналов (как это делает journalctl). Такой подход не приводит к потере структурированных данных, но более чувствителен к ошибкам (например, в случае повреждения журнала) и увеличивает накладные расходы.

Во всех перечисленных ситуациях информация будут проходить через демон syslog, а оттуда их можно отправить в любое место и использовать на своё усмотрение.

Большинство дистрибутивов Linux поставляются с rsyslog. Чтобы пересылать данные на другой сервер через TCP, добавьте следующую строку в /etc/rsyslog.conf:

*.* @@logsene-syslog-receiver.example.com

Эта строка будет заворачивать данные на сервер example.com. Вы можете заменить logsene-syslog-receiver.[…..] именем своего syslog-хоста.

Некоторые демоны могут выводить данные в Elasticsearch через HTTP/HTTPS. Одним из них является наш rsyslog. Например, если вы юзаете rsyslog на Ubuntu, сначала установите модуль Elasticsearch:

sudo apt-get install rsyslog-elasticsearch

Затем в конфигурационном файле вам потребуется поправить два элемента: шаблон JSON для Elasticsearch:

template(name="LogseneFormat" type="list" option.json="on") {
 constant(value="{")
 constant(value="\"@timestamp\":\"")
 property(name="timereported" dateFormat="rfc3339")
 constant(value="\",\"message\":\"")
 property(name="msg")
 constant(value="\",\"host\":\"")
 property(name="hostname")
 constant(value="\",\"severity\":\"")
 property(name="syslogseverity-text")
 constant(value="\",\"facility\":\"")
 property(name="syslogfacility-text")
 constant(value="\",\"syslog-tag\":\"")
 property(name="syslogtag")
 constant(value="\",\"source\":\"")
 property(name="programname")
 constant(value="\"}")
}

и action, который пересылает данные в Elasticsearch, используя указанный выше шаблон:

module(load="omelasticsearch")
action(type="omelasticsearch"
 template="LogseneFormat" # шаблон,объявленный ранее
 searchIndex="LOGSENE_APP_TOKEN_GOES_HERE"
 server="logsene-receiver.example.com"
 serverport="443"
 usehttps="on"
 bulkmode="on"
 queue.dequeuebatchsize="100" # сколько сообщений отправлять за раз
 action.resumeretrycount="-1") # буфер сообщений

В приведенном примере показано, как отправлять сообщения в API Elasticsearch на example.com. Настройте action на ваш локальный Elasticsearch:

  • searchIndex – будет вашим алиасом;
  • server – имя хоста (ноды) Elasticsearch;
  • serverport может быть 9200 или кастомным, главное, чтобы на нем слушал Elasticsearch;
  • usehttps= "off" – отправление данных по http.

Независимо от того, используете ли вы syslog-протокол или что-то еще, лучше перенаправлять данные непосредственно из демона, чем искать проблемы в отдельных файлах из /var/log.

Это не значит, что файлы в /var/log бесполезны. Они пригодятся в следующих случаях:

  • приложения пишут туда свои логи, например, HTTP, FTP, MySQL и т. д.,
  • требуется обработать системные журналы, например, с помощью grep.

Важные файлы журналов для мониторинга

Здесь мы рассмотрим ключевые файлы логов, какую информацию они хранят, как настраивается rsyslog для записи и как посмотреть информацию с помощью journalctl.

Журнал /var/log/syslog или /var/log/messages

Это «всеохватывающий» системный лог:

# logger "this is a test"
# tail -1 /var/log/syslog
May 7 15:33:11 ubuntu-bionic test-user: this is a test

Вы найдёте здесь все сообщения: ошибки, информационные сообщения и все другие серьёзности. Исключением является stop action.

Если в /var/log/syslog или /var/log/messages пусто, скорее всего, journald не перенаправляет данные в syslog. Все те же данные можно просмотреть, вызвав journalctl без параметров.

# journalctl --no-pager | grep "this is a test"
May 07 15:33:11 ubuntu-bionic test-user[7526]: this is a test
Журналы /var/log/kern.log или /var/log/dmesg

Сюда по умолчанию отправляются сообщения ядра:

Apr 17 16:47:28 ubuntu-bionic kernel: [ 0.004000] console [tty1] enabled

И снова, если у вас нет syslog (или файл пустой/отсутствует) – используйте journalctl:

kern.* /var/log/kern.log
Журналы /var/log/auth.log или /var/log/secure

Здесь вы найдете сообщения об аутентификации, генерируемые такими службами, как sshd:

May 7 15:03:09 ubuntu-bionic sshd[1202]: pam_unix(sshd:session): session closed for user vagrant

Вот ещё один фильтр по значениям auth и authpriv:

auth,authpriv.* /var/log/auth.log

Вы можете использовать такие фильтры в journalctl, используя числовые уровни объектов:

# journalctl SYSLOG_FACILITY=4 SYSLOG_FACILITY=10
…
May 7 15:03:09 ubuntu-bionic sshd[1202]: pam_unix(sshd:session): session closed for user vagrant
…
Журнал /var/log/cron.log

Сюда отправляются ваши cron-сообщения (jobs-ы, выполняемые регулярно):

May 06 08:19:01 localhost.localdomain anacron[1142]: Job `cron.daily' started

Пример фильтра:

cron.* /var/log/cron

С journalctl можно сделать так:

# journalctl SYSLOG_FACILITY=9
Журнал /var/log/mail.log или /var/log/maillog

Практически все демоны (такие как Postfix, cron и т. д.) обычно пишут свои логи в syslog. Затем rsyslog раскладывает эти логи по файлам:

mail.* /var/log/mail.log

С помощью journald просматривать журналы можно так:

# journalctl SYSLOG_FACILITY=2

Подведём итоги

  • Расположение и формат системных журналов Linux зависят от того, как настроен дистрибутив.
  • Большинство дистрибутивов имеют systemd, и все логи «живут» там. Чтобы что-то просмотреть и найти, используйте journalctl.
  • Некоторые дистрибутивы передают системные журналы в syslog, либо напрямую, либо через journal. В этом случае у вас, скорее всего, есть логи, записанные в отдельные файлы в /var/log.
  • Если вы управляете несколькими серверами, вам потребуется централизовать журналирование с помощью специального ПО или использовать собственный ELK-стек.

Логгирование событий невероятно важная и серьёзная штука в любой сфере администрирования и ОС. Рекомендуем отнестись ответственно к данной теме – она будет полезна при дебагинге, разработке и просто в управлении инфраструктурой.

Как правильно писать логи (?) / Хабр

Тема может и банальная, но когда программа начинает работать как то не так, и вообще вести себя очень странно, часто приходится читать логи. И много логов, особенно если нет возможности отлаживать программу и не получается воспроизвести ошибку. Наверно каждый выработал для себя какие то правила, что, как и когда логировать. Ниже я хочу рассмотреть несколько правил записи сообщений в лог, а также будет небольшое сравнение библиотек логирования для языков php, ruby и go. Сборщики логов и системы доставки не будут рассматриваться сознательно (их обсуждали уже много раз).

Есть такая linux утилита, а также по совместительству сетевой протокол под названием syslog. И есть целый набор RFC посвящённый syslog, один из них описывает уровни логирования https://en.wikipedia.org/wiki/Syslog#Severity_level (https://tools.ietf.org/html/rfc5424). Согласно rfc 5424 для syslog определено 8 уровней логирования, для которых также дается краткое описание. Данные уровни логирования были переняты многими популярными логерами для разных языков программирования. Например, http://www.php-fig.org/psr/psr-3/ определяет те же самые 8 уровней логирования, а стандартный Ruby logger использует немного сокращённый набор из 5 уровней. Несмотря на формальное указание в каких случаях должен быть использован тот или иной уровень логов, зачастую используется комбинация вроде debug/info/fatal — первый для логирования во время разработки и тестирования, второй и третий в расчёте на продакшен. Потом в какой то момент на продакшене начинает происходить что то не понятное и вдруг оказывается, что info логов не хватает — бежим включать debug. И если они не сильно нагружают систему, то зачастую так и остаются включенными в продакшен окружении. По факту остаётся два сценария, когда нужно иметь логи:
  • что-то происходит и надо знать что
  • что-то сломалось и нужно дополнительно активировать триггер

По триггеру может происходить: уведомление об ошибке на email, аварийное завершение или перезапуск программы или другие типичные сценарии.

В языке Go в котором всё упрощено до предела, стандартный логер тоже прилично покромсали и оставили следующие варианты:

  • Fatal — вывод в лог и немедленный выход в ОС.
  • Panic — вывод в лог и возбуждение «паники» (аналог исключения)
  • Print — просто выводит сообщение в лог

Запутаться, что использовать в конкретной ситуации уже практически невозможно. Но сообщения в таком сильно усеченном виде сложно анализировать, а также настраивать системы оповещения, типично реагирующих на какой нибудь Alert\Fatal\Error в тексте лога.

Я часто при написании программы с нуля повсеместно использую debug уровень для логирования с расчётом, что на продакшене будет выставлен уровень логирования info и тем самым сократится зашумлённость сообщениями. Но в таком подходе часто возникают ситуация, что логов вдруг становится не хватать. Трудно угадать, какая информация понадобиться, что бы отловить редкий баг. Возможно рационально всегда использовать по умолчанию уровень info, а в обработчиках ошибок уровень error и выше. Но если у вас сотни и больше сообщений лога в секунду, то тогда наверно есть смысл тонкой настройки между info/debug. В таких ситуациях уже имеет смысл использовать специализированные решения что бы не просаживать производительность.

Есть ещё тонкий момент, когда вы пишите что то вроде logger.debug(entity.values) — то при выставленном уровне логирования выше debug содержимое entity.values не попадёт в лог, но оно каждый раз будет вычисляться отъедая ресурсы. В Ruby логеру можно передать вместо строки сообщения блок кода: Logger.debug { entity.values }. В таком случае вычисления будут происходить только при выставленном соответствующем уровне лога. В языке Go для реализации ленивого вычисления в логер можно передать объект поддерживающий интерфейс Stringer.

После того, как разобрались с использованием уровней логов, нужно ещё уметь связывать разрозненные сообщения, особенно это актуально для многопоточных приложений или связанных между собой отдельных сервисов, когда в логах все сообщения оказываются вперемешку.

Типичный формат строки сообщения в логе можно условно разделить на следующие составные части:

[system info] + [message] + [context]

Где:
  • system info: метка времени, ид процесса, ид потока и другая служебная информация
  • message: текст сообщения
  • context: любая дополнительная информация, контекст может быть общим для сообщений в рамках какой то операции.

Для того, чтобы связать пары запрос\ответ часто используется http заголовок X-Request-ID. Такой заголовок может сгенерировать клиент, или он может быть сгенерирован на стороне сервера. Добавив его в контекст каждой строчки лога появится возможность лёгким движением руки найти все сообщения возникшие в рамках выполнения конкретного запроса. А в случае распределенных систем, заголовок можно передавать дальше по цепочке сетевых вызовов.

Но с единым контекстом в рамках запроса возникает проблема с различными ORM, http клиентами или другими сервисами\библиотеками, которые живут своей жизнью. И ещё хорошо, если они предоставляют возможность переопределить свой стандартный логер хотя бы глобально, а вот выставить контекст для логера в рамках запроса зачастую не реально. Данная проблема в основном актуальна для многопоточной обработки, когда один процесс обслуживает множество запросов. Но например в фрэймворке Rails имеется очень тесная интеграция между всеми компонентами и запросы ActiveRecord могут писаться в лог вместе с глобальным контекстом для текущего сетевого запроса. А в языке Go некоторые библиотеки логирования позволяют динамически создавать новый объект логера с нужным контекстом, выглядит это примерно так:

reqLog := log.WithField("requestID", requestID)

После этого такой экземпляр логера можно передать как зависимость в другие объекты. Но отсутствие стандартизированного интерфейса логирования (например как psr-3 в php) провоцирует создателей библиотек хардкодить малосовместимые реализации логеров. Поэтому если вы пишите свою библиотеку на Go и в ней есть компонент логирования, не забудьте предусмотреть интерфейс для замены логера на пользовательский.

Резюмируя:

  • Логируйте с избытком. Никогда заранее не известно сколько и какой информации в логах понадобится в критический момент.
  • Восемь уровней логирования — вам действительно столько надо? По опыту должно хватить максимум 3-4, и то при условии, что для них настроены обработчики событий.
  • По возможности используйте ленивые вычисления для вывод сообщений в лог
  • Всегда добавляйте текущий контекст в каждое сообщение лога, как минимум requestID.
  • По возможности настраивайте сторонние библиотеки таким образом, чтобы они использовали логер с текущим контекстом запроса.

Собираем логи с Loki / Блог компании Badoo / Хабр

Мы в Badoo постоянно мониторим свежие технологии и оцениваем, стоит ли использовать их в нашей системе. Одним из таких исследований и хотим поделиться с сообществом. Оно посвящено Loki — системе агрегирования логов.

Loki — это решение для хранения и просмотра логов, также этот стек предоставляет гибкую систему для их анализа и отправки данных в Prometheus. В мае вышло очередное обновление, которое активно продвигают создатели. Нас заинтересовало, что умеет Loki, какие возможности предоставляет и в какой степени может выступать в качестве альтернативы ELK — стека, который мы используем сейчас.


Что такое Loki

Grafana Loki — это набор компонентов для полноценной системы работы с логами. В отличие от других подобных систем Loki основан на идее индексировать только метаданные логов — labels (так же, как и в Prometheus), a сами логи сжимать рядом в отдельные чанки.

Домашняя страница, GitHub

Прежде чем перейти к описанию того, что можно делать при помощи Loki, хочу пояснить, что подразумевается под «идеей индексировать только метаданные». Сравним подход Loki и подход к индексированию в традиционных решениях, таких как Elasticsearch, на примере строки из лога nginx:

172.19.0.4 - - [01/Jun/2020:12:05:03 +0000] "GET /purchase?user_id=75146478&item_id=34234 HTTP/1.1" 500 8102 "-" "Stub_Bot/3.0" "0.001"

Традиционные системы парсят строку целиком, включая поля с большим количеством уникальных значений user_id и item_id, и сохраняют всё в большие индексы. Преимуществом данного подхода является то, что можно выполнять сложные запросы быстро, так как почти все данные — в индексе. Но за это приходится платить тем, что индекс становится большим, что выливается в требования к памяти. В итоге полнотекстовый индекс логов сопоставим по размеру с самими логами. Для того чтобы по нему быстро искать, индекс должен быть загружен в память. И чем больше логов, тем быстрее индекс увеличивается и тем больше памяти он потребляет.

Подход Loki требует, чтобы из строки были извлечены только необходимые данные, количество значений которых невелико. Таким образом, мы получаем небольшой индекс и можем искать данные, фильтруя их по времени и по проиндексированным полям, а затем сканируя оставшееся регулярными выражениями или поиском подстроки. Процесс кажется не самым быстрым, но Loki разделяет запрос на несколько частей и выполняет их параллельно, обрабатывая большое количество данных за короткое время. Количество шардов и параллельных запросов в них конфигурируется; таким образом, количество данных, которое можно обработать за единицу времени, линейно зависит от количества предоставленных ресурсов.

Этот компромисс между большим быстрым индексом и маленьким индексом с параллельным полным перебором позволяет Loki контролировать стоимость системы. Её можно гибко настраивать и расширять в соответствии с потребностями.

Loki-стек состоит из трёх компонентов: Promtail, Loki, Grafana. Promtail собирает логи, обрабатывает их и отправляет в Loki. Loki их хранит. А Grafana умеет запрашивать данные из Loki и показывать их. Вообще Loki можно использовать не только для хранения логов и поиска по ним. Весь стек даёт большие возможности по обработке и анализу поступающих данных, используя Prometheus way.
Описание процесса установки можно найти здесь.


Поиск по логам

Искать по логам можно в специальном интерфейсе Grafana — Explorer. Для запросов используется язык LogQL, очень похожий на PromQL, использующийся в Prometheus. В принципе, его можно рассматривать как распределённый grep.

Интерфейс поиска выглядит так:

Сам запрос состоит из двух частей: selector и filter. Selector — это поиск по индексированным метаданным (лейблам), которые присвоены логам, а filter — поисковая строка или регэксп, с помощью которого отфильтровываются записи, определённые селектором. В приведенном примере: В фигурных скобках — селектор, все что после — фильтр.

{image_name="nginx.promtail.test"} |= "index"

Из-за принципа работы Loki нельзя делать запросы без селектора, но лейблы можно делать сколь угодно общими.

Селектор — это key-value значения в фигурных скобках. Можно комбинировать селекторы и задавать разные условия поиска, используя операторы =, != или регулярные выражения:

{instance=~"kafka-[23]",name!="kafka-dev"} 
// Найдёт логи с лейблом instance, имеющие значение kafka-2, kafka-3, и исключит dev 

Фильтр — это текст или регэксп, который отфильтрует все данные, полученные селектором.

Есть возможность получения ad-hoc-графиков по полученным данным в режиме metrics. Например, можно узнать частоту появления в логах nginx записи, содержащей строку index:

Полное описание возможностей можно найти в документации LogQL.


Парсинг логов

Есть несколько способов собрать логи:


  • С помощью Promtail, стандартного компонента стека для сбора логов.
  • Напрямую с докер-контейнера при помощи Loki Docker Logging Driver.
  • Использовать Fluentd или Fluent Bit, которые умеют отправлять данные в Loki. В отличие от Promtail они имеют готовые парсеры практически для любого вида лога и справляются в том числе с multiline-логами.

Обычно для парсинга используют Promtail. Он делает три вещи:


  • Находит источники данных.
  • Прикрепляет к ним лейблы.
  • Отправляет данные в Loki.

В настоящий момент Promtail может читать логи с локальных файлов и с systemd journal. Он должен быть установлен на каждую машину, с которой собираются логи.

Есть интеграция с Kubernetes: Promtail автоматически через Kubernetes REST API узнаёт состояние кластера и собирает логи с ноды, сервиса или пода, сразу развешивая лейблы на основе метаданных из Kubernetes (имя пода, имя файла и т. д.).

Также можно развешивать лейблы на основе данных из лога при помощи Pipeline. Pipeline Promtail может состоять из четырёх типов стадий. Более подробно — в официальной документации, тут же отмечу некоторые нюансы.


  1. Parsing stages. Это стадия RegEx и JSON. На этом этапе мы извлекаем данные из логов в так называемую extracted map. Извлекать можно из JSON, просто копируя нужные нам поля в extracted map, или через регулярные выражения (RegEx), где в extracted map “мапятся” named groups. Extracted map представляет собой key-value хранилище, где key — имя поля, а value — его значение из логов.
  2. Transform stages. У этой стадии есть две опции: transform, где мы задаем правила трансформации, и source — источник данных для трансформации из extracted map. Если в extracted map такого поля нет, то оно будет создано. Таким образом, можно создавать лейблы, которые не основаны на extracted map. На этом этапе мы можем манипулировать данными в extracted map, используя достаточно мощный Golang Template. Кроме того, надо помнить, что extracted map целиком загружается при парсинге, что даёт возможность, например, проверять значение в ней: “{{if .tag}tag value exists{end}}”. Template поддерживает условия, циклы и некоторые строковые функции, такие как Replace и Trim.
  3. Action stages. На этом этапе можно сделать что-нибудь с извлечённым:
    • Создать лейбл из extracted data, который проиндексируется Loki.
    • Изменить или установить время события из лога.
    • Изменить данные (текст лога), которые уйдут в Loki.
    • Создать метрики.
  4. Filtering stages. Стадия match, на которой можно либо отправить в /dev/null записи, которые нам не нужны, либо направить их на дальнейшую обработку.

Покажу на примере обработки обычных nginx-логов, как можно парсить логи при помощи Promtail.

Для теста возьмём в качестве nginx-proxy модифицированный образ nginx jwilder/nginx-proxy:alpine и небольшой демон, который умеет спрашивать сам себя по HTTP. У демона задано несколько эндпоинтов, на которые он может давать ответы разного размера, с разными HTTP-статусами и с разной задержкой.

Собирать логи будем с докер-контейнеров, которые можно найти по пути /var/lib/docker/containers/<container_id>/<container_id>-json.log

В docker-compose.yml настраиваем Promtail и указываем путь до конфига:

promtail:
  image: grafana/promtail:1.4.1
 // ...
 volumes:
   - /var/lib/docker/containers:/var/lib/docker/containers:ro
   - promtail-data:/var/lib/promtail/positions
   - ${PWD}/promtail/docker.yml:/etc/promtail/promtail.yml
 command:
   - '-config.file=/etc/promtail/promtail.yml'
 // ...

Добавляем в promtail.yml путь до логов (в конфиге есть опция «docker», которая делает то же самое одной строчкой, но это было бы не так наглядно):

scrape_configs:
 - job_name: containers

   static_configs:
       labels:
         job: containerlogs
         __path__: /var/lib/docker/containers/*/*log  # for linux only

При включении такой конфигурации в Loki будут попадать логи со всех контейнеров. Чтобы этого избежать, меняем настройки тестового nginx в docker-compose.yml — добавляем логирование поле tag:

proxy:
 image: nginx.test.v3
//…
 logging:
   driver: "json-file"
   options:
     tag: "{{.ImageName}}|{{.Name}}"

Правим promtail.yml и настраиваем Pipeline. На вход попадают логи следующего вида:

{"log":"\u001b[0;33;1mnginx.1    | \u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] \"GET /api/index HTTP/1.1\" 200 0 \"-\" \"Stub_Bot/0.1\" \"0.096\"\n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.66740443Z"}
{"log":"\u001b[0;33;1mnginx.1    | \u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] \"GET /200 HTTP/1.1\" 200 0 \"-\" \"Stub_Bot/0.1\" \"0.000\"\n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.702925272Z"}

Pipeline stage:

 - json:
     expressions:
       stream: stream
       attrs: attrs
       tag: attrs.tag

Извлекаем из входящего JSON поля stream, attrs, attrs.tag (если они есть) и кладём их в extracted map.

 - regex:
     expression: ^(?P<image_name>([^|]+))\|(?P<container_name>([^|]+))$
     source: "tag"

Если удалось положить поле tag в extracted map, то при помощи регэкспа извлекаем имена образа и контейнера.

 - labels:
     image_name:
     container_name:

Назначаем лейблы. Если в extracted data будут обнаружены ключи image_name и container_name, то их значения будут присвоены соотвестующим лейблам.

 - match:
     selector: '{job="docker",container_name="",image_name=""}'
     action: drop

Отбрасываем все логи, у которых не обнаружены установленные labels image_name и container_name.

  - match:
     selector: '{image_name="nginx.promtail.test"}'
     stages:
       - json:
           expressions:
             row: log

Для всех логов, у которых image_name равен nginx.promtail.test, извлекаем из исходного лога поле log и кладём его в extracted map с ключом row.

  - regex:
         # suppress forego colors
         expression: .+nginx.+\|.+\[0m(?P<virtual_host>[a-z_\.-]+) +(?P<nginxlog>.+)
         source: logrow

Очищаем входную строку регулярными выражениями и вытаскиваем nginx virtual host и строку лога nginx.

     - regex:
         source: nginxlog
         expression: ^(?P<ip>[\w\.]+) - (?P<user>[^ ]*) \[(?P<timestamp>[^ ]+).*\] "(?P<method>[^ ]*) (?P<request_url>[^ ]*) (?P<request_http_protocol>[^ ]*)" (?P<status>[\d]+) (?P<bytes_out>[\d]+) "(?P<http_referer>[^"]*)" "(?P<user_agent>[^"]*)"( "(?P<response_time>[\d\.]+)")?

Парсим nginx-лог регулярными выражениями.

    - regex:
           source: request_url
           expression: ^.+\.(?P<static_type>jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
     - regex:
           source: request_url
           expression: ^/photo/(?P<photo>[^/\?\.]+).*$
       - regex:
           source: request_url
           expression: ^/api/(?P<api_request>[^/\?\.]+).*$

Разбираем request_url. С помощью регэкспа определяем назначение запроса: к статике, к фоткам, к API и устанавливаем в extracted map соответствующий ключ.

       - template:
           source: request_type
           template: "{{if .photo}}photo{{else if .static_type}}static{{else if .api_request}}api{{else}}other{{end}}"

При помощи условных операторов в Template проверяем установленные поля в extracted map и устанавливаем для поля request_type нужные значения: photo, static, API. Назначаем other, если не удалось. Теперь request_type содержит тип запроса.

       - labels:
           api_request:
           virtual_host:
           request_type:
           status:

Устанавливаем лейблы api_request, virtual_host, request_type и статус (HTTP status) на основании того, что удалось положить в extracted map.

       - output:
           source: nginx_log_row

Меняем output. Теперь в Loki уходит очищенный nginx-лог из extracted map.

После запуска приведённого конфига можно увидеть, что каждой записи присвоены метки на основе данных из лога.

Нужно иметь в виду, что извлечение меток с большим количеством значений (cardinality) может существенно замедлить работу Loki. То есть не стоит помещать в индекс, например, user_id. Подробнее об этом читайте в статье “How labels in Loki can make log queries faster and easier”. Но это не значит, что нельзя искать по user_id без индексов. Нужно использовать фильтры при поиске («грепать» по данным), а индекс здесь выступает как идентификатор потока.


Визуализация логов

Loki может выступать в роли источника данных для графиков Grafana, используя LogQL. Поддерживаются следующие функции:


  • rate — количество записей в секунду;
  • count over time — количество записей в заданном диапазоне.

Ещё присутствуют агрегирующие функции Sum, Avg и другие. Можно строить достаточно сложные графики, например график количества HTTP-ошибок:

Стандартный data source Loki несколько урезан по функциональности по сравнению с data source Prometheus (например, нельзя изменить легенду), но Loki можно подключить как источник с типом Prometheus. Я не уверен, что это документированное поведение, но, судя по ответу разработчиков “How to configure Loki as Prometheus datasource? · Issue #1222 · grafana/loki”, например, это вполне законно, и Loki полностью совместим с PromQL.

Добавляем Loki как data source с типом Prometheus и дописываем URL /loki:

И можно делать графики, как в том случае, если бы мы работали с метриками из Prometheus:

Я думаю, что расхождение в функциональности временное и разработчики в будущем это поправят.


Метрики

В Loki доступны возможность извлечения числовых метрик из логов и отправка их в Prometheus. Например, в логе nginx присутствует количество байтов на ответ, а также, при определённой модификации стандартного формата лога, и время в секундах, которое потребовалось на ответ. Эти данные можно извлечь и отправить в Prometheus.

Добавляем ещё одну секцию в promtail.yml:

- match:
   selector: '{request_type="api"}'
   stages:
     - metrics:
         http_nginx_response_time:
           type: Histogram
           description: "response time ms"
           source: response_time
           config:
             buckets: [0.010,0.050,0.100,0.200,0.500,1.0]
- match:
   selector: '{request_type=~"static|photo"}'
   stages:
     - metrics:
         http_nginx_response_bytes_sum:
           type: Counter
           description: "response bytes sum"
           source: bytes_out
           config:
             action: add
         http_nginx_response_bytes_count:
           type: Counter
           description: "response bytes count"
           source: bytes_out
           config:
             action: inc

Опция позволяет определять и обновлять метрики на основе данных из extracted map. Эти метрики не отправляются в Loki — они появляются в Promtail /metrics endpoint. Prometheus должен быть сконфигурирован таким образом, чтобы получить данные, полученные на этой стадии. В приведённом примере для request_type=“api” мы собираем метрику-гистограмму. С этим типом метрик удобно получать перцентили. Для статики и фото мы собираем сумму байтов и количество строк, в которых мы получили байты, чтобы вычислить среднее значение.

Более подробно о метриках читайте здесь.

Открываем порт на Promtail:

promtail:
     image: grafana/promtail:1.4.1
     container_name: monitoring.promtail
     expose:
       - 9080
     ports:
       - "9080:9080"

Убеждаемся, что метрики с префиксом promtail_custom появились:

Настраиваем Prometheus. Добавляем job promtail:

- job_name: 'promtail'
 scrape_interval: 10s
 static_configs:
   - targets: ['promtail:9080']

И рисуем график:

Таким образом можно узнать, например, четыре самых медленных запроса. Также на данные метрики можно настроить мониторинг.


Масштабирование

Loki может быть как в одиночном режиме (single binary mode), так и в шардируемом (horizontally-scalable mode). Во втором случае он может сохранять данные в облако, причём чанки и индекс хранятся отдельно. В версии 1.5 реализована возможность хранения в одном месте, но пока не рекомендуется использовать её в продакшене.

Чанки можно хранить в S3-совместимом хранилище, для хранения индексов — использовать горизонтально масштабируемые базы данных: Cassandra, BigTable или DynamoDB. Другие части Loki — Distributors (для записи) и Querier (для запросов) — stateless и также масштабируются горизонтально.

На конференции DevOpsDays Vancouver 2019 один из участников Callum Styan озвучил, что с Loki его проект имеет петабайты логов с индексом меньше 1% от общего размера: “How Loki Correlates Metrics and Logs — And Saves You Money”.


Сравнение Loki и ELK

Размер индекса

Для тестирования получаемого размера индекса я взял логи с контейнера nginx, для которого настраивался Pipeline, приведённый выше. Файл с логами содержал 406 624 строки суммарным объёмом 109 Мб. Генерировались логи в течение часа, примерно по 100 записей в секунду.

Пример двух строк из лога:

При индексации ELK это дало размер индекса 30,3 Мб:

В случае с Loki это дало примерно 128 Кб индекса и примерно 3,8 Мб данных в чанках. Стоит отметить, что лог был искусственно сгенерирован и не отличался большим разнообразием данных. Простой gzip на исходном докеровском JSON-логе с данными давал компрессию 95,4%, а с учётом того, что в сам Loki посылался только очищенный nginx-лог, то сжатие до 4 Мб объяснимо. Суммарное количество уникальных значений для лейблов Loki было 35, что объясняет небольшой размер индекса. Для ELK лог также очищался. Таким образом, Loki сжал исходные данные на 96%, а ELK — на 70%.

Потребление памяти

Если сравнивать весь стек Prometheus и ELK, то Loki «ест» в несколько раз меньше. Понятно, что сервис на Go потребляет меньше, чем сервис на Java, и сравнение размера JVM Heap Elasticsearch и выделенной памяти для Loki некорректно, но тем не менее стоит отметить, что Loki использует гораздо меньше памяти. Его преимущество по CPU не так очевидно, но также присутствует.

Скорость

Loki быстрее «пожирает» логи. Скорость зависит от многих факторов — что за логи, как изощрённо мы их парсим, сеть, диск и т. д. — но она однозначно выше, чем у ELK (в моём тесте — примерно в два раза). Объясняется это тем, что Loki кладёт гораздо меньше данных в индекс и, соответственно, меньше времени тратит на индексирование. Со скоростью поиска при этом ситуация обратная: Loki ощутимо притормаживает на данных размером более нескольких гигабайтов, у ELK же скорость поиска от размера данных не зависит.

Поиск по логам

Loki существенно уступает ELK по возможностям поиска по логам. Grep с регулярными выражениями — это сильная вещь, но он уступает взрослой базе данных. Отсутствие range-запросов, агрегация только по лейблам, невозможность искать без лейблов — всё это ограничивает нас в поисках интересующей информации в Loki. Это не подразумевает, что с помощью Loki ничего нельзя найти, но определяет флоу работы с логами, когда вы сначала находите проблему на графиках Prometheus, а потом по этим лейблам ищете, что случилось в логах.

Интерфейс

Во-первых, это красиво (извините, не мог удержаться). Grafana имеет приятный глазу интерфейс, но Kibana гораздо более функциональна.


Плюсы и минусы Loki

Из плюсов можно отметить, что Loki интегрируется с Prometheus, соответственно, метрики и алертинг мы получаем из коробки. Он удобен для сбора логов и их хранения с Kubernetes Pods, так как имеет унаследованный от Prometheus service discovery и автоматически навешивает лейблы.

Из минусов — слабая документация. Некоторые вещи, например особенности и возможности Promtail, я обнаружил только в процессе изучения кода, благо open-source. Ещё один минус — слабые возможности парсинга. Например, Loki не умеет парсить multiline-логи. Также к недостаткам можно отнести то, что Loki — относительно молодая технология (релиз 1.0 был в ноябре 2019 года).


Заключение

Loki — на 100% интересная технология, которая подходит для небольших и средних проектов, позволяя решать множество задач агрегирования логов, поиска по логам, мониторинга и анализа логов.

Мы не используем Loki в Badoo, так как имеем ELK-стек, который нас устраивает и который за много лет оброс различными кастомными решениями. Для нас камнем преткновения является поиск по логам. Имея почти 100 Гб логов в день, нам важно уметь находить всё и чуть-чуть больше и делать это быстро. Для построения графиков и мониторинга мы используем другие решения, которые заточены под наши нужды и интегрированы между собой. У стека Loki есть ощутимые плюсы, но он не даст нам больше, чем у нас есть, и его преимущества точно не перекроют стоимость миграции.

И хотя после исследования стало понятно, что мы Loki использовать не можем, надеемся, что данный пост поможет вам в выборе.

Репозиторий с кодом, использованным в статье, находится тут.

Собираем, парсим и отдаём логи с помощью Logstash / Хабр

Приветствую.

Так уж сложилось, что по долгу работы мне приходится много времени уделять логам. Это и участие в выработке правил и политик сбора/хранения/использования логов, это и разбор разных инцидентов и обнаружение аномалий. За сутки наши программы, сервисы и серверы генерируют ОЧЕНЬ большое количество логов. И потребность копания в логах растёт постоянно.
Мне довелось поработать с коммерческими лог-менеджмент продуктами типа ArcSight, RSA Envision, Q1 Labs. У этих продуктов есть как плюсы, так и минусы. Но в статье речь пойдёт не о них.
Речь будет о Logstash.

Что же такое Logstash? Зачем он нужен? Что он умеет?

Logstash — это орудие для сбора, фильтрации и нормализации логов. Оно является бесплатным и open source приложением. Тип лицензии Apache 2.0.

Первой моё знакомство с LS (Logstash) произошло более года назад, и с того времени я очень плотно на него подсел. Мне нравится его идея и возможности. Для меня Logstash — это подобие мясорубки. Неважно что заходит в неё, но после не сложных манипуляций, на выходе всегда красиво и понятно оформленная информация.

Формат конфигурационного файла Logstash’а прост и понятен. Он состоит из трёх частей:

input {
  ...
}

filter {
  ...
}

output {
  ...
}

Входных, фильтрующих и выходных (или выходящих?) блоков может быть любое количество. Всё зависит от ваших потребностей и возможностей железа.
Пустые строки и строки начинающиеся с # — Logstash игнорирует. Так что комментирование конфигурационных файлов не вызовет никаких проблем.
1. INPUT
Данный метод является входной точкой для логов. В нём определяет по каким каналам будут логи попадать в Logstash.
В этой статье я попытаюсь вас ознакомит с основными типами, которые я использую — это file, tcp и udp.
1.1 fileПример конфигурации, для работы с локальными лог-файлами:
input {
  file {
    type => "some_access_log"
    path => [ "/var/log/vs01/*.log", "/var/log/vs02/*.log" ]
    exclude => [ "*.gz", "*.zip", "*.rar" ]
    start_position => "end"
    stat_interval => 1
    discover_interval => 30
  }
}

Построчное описание настроек:

type => "some_access_log"
тип/описание лога. При использовании нескольких входных блоков, удобно их разделять для последующих действий в filter или output.
path => [ "/var/log/vs01/*.log", "/var/log/vs02/*.log" ]
указывается путь к лог-файлам, которые подлежат обработке. Путь должен быть абсолютным (/path/to/logs/), а не относительным (../../some/other/path/).
exclude => [ "*.gz", "*.zip", "*.rar" ]
исключает из обработки файлы с соответствующими расширениями.
start_position => "end"
ждёт появления новых сообщений в конце файла. При обработки уже имеющихся логов, можно выставить «beginning», тогда обработка логов будет происходить построчно с начала файлов.
stat_interval => 1
как часто (в секундах) проверять файлы на изменения. При больших значения, уменьшится частота системных вызовов, но так же увеличится время чтения новых строк.
discover_interval => 30
время (в секундах) через которое будет обновлён список обрабатываемых файлов указанных в path.

1.2 tcpПример конфигурации, для работы с логами удалённых сервисов:
input {
  tcp {
    type => "webserver_prod"
    data_timeout => 10
    mode => "server"
    host => "192.168.3.12"
    port => 3337
  }
}

Построчное описание настроек:

type => "webserver_prod"
тип/описание лога.
data_timeout => 10
время (в секундах), по истечении которого не активное tcp соединение будет закрыто. Значение -1 — соединение всегда будет открыто.
mode => "server"
host => "192.168.3.12"
port => 3337
в этом случае Logstash становится сервером, и начинает слушать на 192.168.3.12:3337. При установке mode => «client» Logstash будет присоединятся к удалённому ip:port для забора логов.
1.3 udpДля udp настройки аналогичные tcp:
input {
  udp {
    type => "webserver_prod"
    buffer_size => 4096
    host => "192.168.3.12"
    port => 3337
  }
}

2. FILTER
В данном блоке настраиваются основные манипуляции с логами. Это может быть и разбивка по key=value, и удаление ненужных параметров, и замена имеющихся значений, и использование geoip или DNS запросов для ип-адресов или названий хостов.

На первый взгляд применение фильтров может показаться сложным и нелогичным, но это не совсем так.

2.1 grokПример конфигурационного файла для основной нормализации логов:
filter {
  grok {
    type => "some_access_log"
    patterns_dir => "/path/to/patterns/"
    pattern => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"
  }
}

Построчное описание настроек:

type => "apache_access"
тип/описание лога. Здесь надо указать тот тип (type), который прописан в блоке input для которого будет происходить обработка.
patterns_dir => "/path/to/patterns/"
путь к каталогу, содержащим шаблоны обработки логов. Все файлы находящиеся в указанной папке будут загружены Logstash, так что лишние файлы там не желательны.
pattern => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"
указывается шаблон разборки логов. Шаблон можно использовать либо в конфигурационном файле, либо из файла шаблонов. Что бы не путаться, я для каждого формата логов создаю отдельный шаблонный файл.Подробнее про шаблоныС помощью grok фильтра можно структурировать большую часть логов — syslog, apache, nginx, mysql итд, записанных в определённом формате.
Logstash имеет более 120 шаблонов готовых регулярных выражений (regex). Так что написание фильтров для обработки большинства логов не должно вызвать особого страха или недопонимания.

Формат шаблонов относительно простой — NAME PATTERN, то есть построчно указывается имя шаблона и ему соответствующее регулярное выражение. Пример:

NUMBER \d+
WORD \b\w+\b
USERID [a-zA-Z0-9_-]+

Можно использовать любой ранее созданный шаблон:
USER %{USERID}

Шаблоны можно так же и комбинировать:
CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4})
WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})
MAC (?:%{CISCOMAC}|%{WINDOWSMAC})

Допустим формат логов у нас следующий:
55.3.244.1 GET /index.html 15824 0.043

Среди готовых шаблонов, к счастью уже имеются некоторые регулярные выражения и не надо придумывать колёсное транспортное средство, приводимое в движение мускульной силой человека через ножные педали или через ручные рычаги (это я про велосипед если что).
С данным примером лога достаточно pattern записать в виде «%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}«, в этом случае все логи с данным форматом будут уже иметь некую логическую структуру.
После обработки наша строка будет выглядеть следующим образом:

client: 55.3.244.1
method: GET
request: /index.html
bytes: 15824
duration: 0.043

Со списком готовых grok-шаблонов можно познакомиться здесь.



2.2 mutateПример конфигурационного файла для изменения/удаления записей из логов:
filter {
  mutate {
    type => "apache_access"
    remove => [ "client" ]
    rename => [ "HOSTORIP", "client_ip" ]
    gsub => [ "message", "\\/", "_" ]
    add_field => [ "sample1", "from %{clientip}" ]
  }
}

Построчное описание настроек:
type => "apache_access"
тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.
remove => [ "client" ]
удаление всех данных имеющих название поля client. Возможно указание нескольких названий полей.
rename => [ "HOSTORIP", "client_ip" ]
переименование название поля HOSTORIP в client_ip.
gsub => [ "message", "\\/", "_" ]
замена всех «/» на «_» в поле messages.
add_field => [ "sample1", "from %{clientip}" ]
добавление нового поля «sample1» со значением «from %{clientip}». Допускается использование названий переменных.

2.3 dateПример конфигурационого файла:
filter {
  date {
    type => "apache_access"
    match => [ "timestamp", "MMM dd HH:mm:ss" ]
  }
}

Построчное описание настроек:
type => "apache_access"
тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.
match => [ "timestamp", "MMM dd HH:mm:ss" ]
временная метка события. Важная настройка для дальнейшей возможности сортировки или выборки логов. Если в логах время указано в unix timestamp (squid), то следует использовать match => [ «timestamp», «UNIX» ]

2.4 kvПример конфигурационного файла для обработки логов в формате key=value:
filter {
  kv {
    type => "custom_log"
    value_split => "=:"
    fields => ["reminder"]
    field_split => "\t?&"
  }
}

Построчное описание настроек:
type => "custom_log"
тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.
value_split => "=:"
использовать символы «=» и «:» для разделения ключа-значения.
fields => ["reminder"]
название поля в котором искать ‘ключ=значение’. По умолчанию разбивка будет происходить для всей строки лога.
field_split => "\t?&"
использовать символы «\t?&» для разделения ключей. \t — знак табулятора

2.5 multilineПример конфигурационного файла для «склеивания» многострочных логов (например Java stack trace):
filter {
  multiline {
    type => "java_log"
    pattern => "^\s"
    what => "previous"
  }
}

Построчное описание настроек:
type => "java_log"
тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.
pattern => "^\s"
регулярное выражение
what => "previous"
при соответствии шаблону «pattern» строка принадлежит предыдущей (previous) строке.
3. OUTPUT
Название этого блока/метода говорит само за себя — в нём указываются настройки для исходящих сообщений. Аналогично предыдущим блокам, здесь можно указывать любое количество исходящих подблоков.
3.1 stdoutПример конфигурационного файла для вывода логов в standard output:
output {
  stdout {
    type => "custom_log"
    message => "IP - %{clientip}. Full message: %{@message}. End of line."
  }
}
type => "custom_log"
тип/описание лога.
message => "clIP - %{clientip}. Full message: %{@message}. End of line."
указывается формат исходящего сообщения. Допустимо использование переменных после grok-фильтрации.

3.2 fileПример конфигурационого файла для записи логов в файл:
output {
  file {
    type => "custom_log"
    flush_interval => 5
    gzip=> true
    path => "/var/log/custom/%{clientip}/%{type}"
    message_format => "ip: %{clientip} request:%{requri}"
  }
}
type => "custom_log"
тип/описание лога.
flush_interval => 5
интервал записи исходящих сообщений. Значение 0 будет записывать каждое сообщение.
gzip=> true
файл исходящих сообщений будет сжат Gzip.
path => "/var/log/custom/%{clientip}/%{type}"
путь и название файла куда будут сохраняться исходящие сообщения. Можно использовать переменные. В данном примере, для каждого уникального IP адреса будет создана своя папка и сообщения будут записываться в файл соответствующий переменной %{type}.
message_format => "ip: %{clientip} request:%{requri}"
формат исходящего сообщения.

3.3 elasticsearchПример конфигурационного файла для записи логов в базу Elasticsearch:
output {
  elasticsearch {
    type => "custom_log"
    cluster => "es_logs"
    embedded => false
    host => "192.168.1.1"
    port => "19300"
    index => "logs-%{+YYYY.MM.dd}" 
  }
}
type => "custom_log"
тип/описание лога.
cluster => "es_logs"
название кластера указанного в cluster.name в настроечном файле Elasticsearch.
embedded => false
указывает какую базу Elasticsearch использовать внутреннюю или стороннюю.
port => "19300"
транспортный port Elasticsearch.
host => "192.168.1.1"
IP адрес Elasticsearch
index => "logs-%{+YYYY.MM.dd}" 
название индекса куда будут записываться логи.

3.4 emailДанный плагин можно использовать для алертов. Минус в том, что любые изменения уведомлений (в принципе как и любых других настроек) требуют перезапуск logstash программы, но разработчик говорит, что возможно в будущем этого не придётся делать.
Пример конфигурационого файла:
output {
  email {
    type => "custom_log"
    from => "[email protected]"
    to => "[email protected]"
    cc => "[email protected]"
    subject => "Found '%{matchName}' Alert on %{@source_host}"
    body => "Here is the event line %{@message}"
    htmlbody => "<h3>%{matchName}</h3><br/><br/><h4>Full Event</h4><br/><br/><div align='center'>%{@message}</div>"
    via => "sendmail"
    options => [ "smtpIporHost", "smtp.gmail.com",
                          "port", "587",
                          "domain", "yourDomain",
                          "userName", "yourSMTPUsername",
                          "password", "PASS",
                          "starttls", "true",
                          "authenticationType", "plain",
                          "debug", "true"
                         ]
    match => [ "response errors", "response,501,,or,response,301",
                        "multiple response errors", "response,501,,and,response,301" ]

  }
}
type => "custom_log"
тип/описание лога.
from => "[email protected]"
to => "[email protected]"
cc => "[email protected]"
если у вас хватило сил дочитать до этих строк, значит вы можете сами определить смысл этих 3х настроек 🙂
subject => "Found '%{matchName}' Alert on %{@source_host}"
тема письма уведомления. Можно использовать переменные. Например %{matchName} — название условия совпадения из настройки «match».
body => "Here is the event line %{@message}"
htmlbody => "<h3>%{matchName}</h3><br/><br/><h4>Full Event</h4><br/><br/><div align='center'>%{@message}</div>"
тело письма.
via => "sendmail"
способ отсылки письма. Возможен один вариант из двух — smtp или sendmail.
options => ...
стандартные настройки почтовых параметров.
match => [ "response errors", "response,501,,or,response,301",
                    "multiple response errors", "response,501,,and,response,301" ]
«response errors» — название алерта (записывается в переменную %{matchName}). «response,501,,or,response,301» — критерии срабатывания алертов. В данном примере если поле response содержит значение 501 или 301, то алерт считается сработавшим. Во второй строке используется логика AND, т.е. оба условия должны быть выполнены.
4. Итого

Создаём файл habr.conf:
input {
  tcp {
    type => "habr"
    port => "11111"
  }
}
filter {
  mutate {
    type => "habr"
    add_field => [ "habra_field", "Hello Habr" ]
  }
}
output {
  stdout {
    type => "habr"
    message => "%{habra_field}: %{@message}"
  }
}

Запускаем Logstash:
java -jar logstash-1.1.9-monolithic.jar agent -f ./habr.conf

Проверяем, что Logstash запущен:
# netstat -nat |grep 11111
Если порт 11111 присутствует, значит Logstash готов принимать логи.

В новом терминальном окне пишем:
echo "Logs are cool!" | nc localhost 11111

Смотрим результат в окне где запущен Logstash. Если там появилось секретное послание, значит всё работает.

P.s.Последнюю версию Logstash можно скачать отсюда.

Спасибо за внимание,

журналов Warcraft — анализ боя для Warcraft

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

Интеграция с Battle.net

После того, как вы подписались на журналы Warcraft, вы можете интегрировать свою учетную запись в Battle.сеть. Это дает WCL доступ к вашим персонажам и гильдиям. Вы можете перейти в настройки пользователя для интеграции с Battle.net.

Что такое журнал боя?

Журнал боя — файл, созданный игрой. который содержит серию событий. Эти события содержат информацию, например, какие способности использовала ваша команда, какой урон они нанесли и кому, и какое исцеление. был получен.

Идея, лежащая в основе регистрации боевых действий , довольно проста: записать, что произошло, чтобы это можно было отправить на веб-сайт для анализа.

Включение ведения журнала боя

Перед тем, как выполнять вход в World of Warcraft, вам необходимо убедиться, что включен расширенный журнал боя. Это необходимо для журналов быть принятым на сайте. Перейдите на панель «Сеть» в системных настройках в игре.

Advanced Combat Logging должен быть включен перед тем, как вы будете вести журнал!

Чтобы включить ведение журнала боя в World of Warcraft, просто перейдите в окно чата и введите / combatlog. Это все, что вам нужно сделать! Теперь все, что ты а игроки и враги вокруг вас будут записаны в файл WoWCombatLog.текст. Этот файл находится в подкаталоге Logs вашей установки WoW. Когда все будет готово, вы можете просто выйти из игры или снова ввести / combatlog, чтобы отключить выход.

Я включил вход и попал в манекен-мишень, но в этот файл ничего не записывается! Что дает?

Вне рейдов файл журнала боя записывается только при возникновении определенного количества событий. Это означает, что обновление может быть очень медленным. если вы просто делаете сольный контент в мире.

Есть ли надстройки, помогающие мне вести журнал боя?

Да. Вы можете использовать такие надстройки, как Loggerhead, DBM или Ask Mr. Robot, чтобы логирование автоматически включалось в рейдах и выключалось, когда вы уходите. Это очень Однако при использовании журналов Warcraft важно, чтобы вы регистрировали весь рейд. Функция автоматического ведения журнала DBM, например, регистрирует только боссов, и это приведет к это, чтобы не регистрировать вызов домашних животных. Это может привести к проблемам, когда домашние животные не будут связаны с хозяевами.

По возможности мы всегда рекомендуем записывать всю ночь рейда.Не оставляйте вне журнала хлам и события, происходящие вне боя.

Загрузка журналов

Для загрузки журналов на веб-сайт вы используете клиентское приложение. Это приложение можно получить здесь. Если у вас возникли проблемы с получением приложение для запуска или установки, мы рекомендуем вам обратиться за помощью на форумы, поскольку, вероятно, кто-то еще столкнулся с той же проблемой и может помочь.

Два вида лесозаготовок

Есть два способа ведения журнала.Первый — загрузить весь файл журнала после завершения рейда. Второй способ — это сделать то, что мы называем , ведение журнала в реальном времени . В этом В модели клиент контролирует файл журнала и всякий раз, когда видит новые события, прикрепленные к концу файла, он отправляет эти события на веб-сайт. Живая регистрация режим отлично подходит, когда вы хотите изучить салфетки сразу после того, как они произошли, чтобы увидеть, что пошло не так.

Куда уходят журналы?

У вас есть два варианта выбора, куда загружать журналы.Каждый пользователь в журналах Warcraft получает личное пространство журнала только для них, так что вы всегда можете загрузить ваши журналы там, даже не вступая в гильдию.

Второй вариант загрузки журналов — это загрузка журналов в зону вашей гильдии. Когда вы это сделаете, все в гильдии смогут видеть журналы. Думайте об этом как об общем место для официальных рейдов вашей гильдии.

Прежде чем вы сможете загружать журналы в гильдию, вы должны сначала присоединиться к гильдии. Если гильдии не существует, вы также можете создать гильдию.

Гильдии

[Примечание: эта страница находится в разработке.] ,31 HP в журнале вызывал отрицательное исцеление.
  • Добавлено определение класса и спецификации для охотников на демонов
  • Обновлено определение спецификаций для медвежьих друидов, кровавых рыцарей смерти, дисциплинарных священников и охотников за выживанием.
  • Исправлен клиент для новой строки COMBATANT_INFO, вызывающий переполнение, слишком много запятых.
  • Исправлен инструмент проверки лидера гильдии, в нем использовалась старая версия API сообщества Battle.net, которая перестала работать.
  • * шишка *

    Автор: Майлз 20 марта 2015 г., 11:50 CET

    Как вы, наверное, заметили, страницы тактического обзора для всех боссов текущего уровня рейда были добавлены некоторое время назад.Пока ничего нового, но есть кое-что, что упростит вам рейды.

    Последние изменения (18/12)

    Автор: Майлз 18 декабря 2014 г., 20:50 CET

    Сегодня особо не на что смотреть, так что вот небольшой дамп из журналов фиксации за последние 2 дня

      На странице рейтинга гильдии
    • (Старая) удален случайный столбец.
    • Исправлена ​​опция? Type = json на страницах рейтинга, данные были неполными. И теперь вы знаете, что он существует.
    • Обновлен поток данных отчетов гильдий (/ feeds / guilds / [id] / raids), они были забыты в результате большого изменения копирования и замены для моделей внутренней базы данных. И теперь вы знаете, что он существует. Для вариантов добавьте? T = plain / xml / json.
    • Изменен глобальный тайм-аут бэкэнда на индивидуальный, индивидуальные настройки позволяют более плавно обновлять журналы большего размера.
    • Во время профилирования обнаружены 2 точки доступа в серверной части:
      • Улучшена производительность конкатенации BitArray, уменьшены накладные расходы на загрузку отчета.(+ 15% ускорение загрузки)
      • Улучшена производительность слияния игрока и питомца, больше работы вынесено за пределы внутреннего цикла. (+ 15% ускорение загрузки)
      • -> больше ресурсов процессора для новых вещей. Ура! Не то, чтобы у нас вообще не хватало ресурсов ЦП, на данный момент очень много ресурсов — но, хотя вы можете купить пропускную способность (больше страниц в секунду), вы не можете улучшить задержку с помощью денег (время, необходимое для рендеринга 1 страницы)

    Последние 2 босса добавлены в тактический обзор

    Автор: Майлз 16 декабря 2014 г., 16:48 CET

    Brackenspore и Twin Ogron были добавлены в Tactical Overview, а сама страница была немного изменена.

    • Добавлен наведение курсора на графики ауры, чтобы показать, кто это такая точка данных — это необходимо для переполненных графиков.
    • Добавлена ​​автоматическая раскраска, поэтому 4 друида не будут иметь одинаковый цвет

    И я перехожу к следующей функции, которую нужно кодировать. Идеи? Напишите мне на [email protected] или разместите сообщение на форуме.

    О да, я получил тычок насчет Стэггера. Это было в списке дел целую вечность, но, поскольку это действительно раздражающая способность отслеживать, пока прототипы не работают так хорошо.Есть идея? Ткните меня.

    Ко’гат добавил

    Автор: Майлз 12 декабря 2014 г., 18:29 CET

    Ко’раг <Разрушитель магии> был добавлен в тактический обзор с поддержкой отображения статуса Обнуляющего Барьера, стеков Силы Разрушителя, обработки переполнения энергии, Дестабилизации (добавлений) и Изгнания магии.

    Если у вас есть идеи, что добавить, дайте нам знать, и мы постараемся добавить это до следующего рейда.

    Знакомство с тактическим обзором

    Автор: Майлз 11 декабря 2014 г., 20:12 CET

    Это в основном:

    Одно из недавних изменений в серверной части — сделать все, что угодно, можно быстро и графически. Это означает, что теперь мы можем отобразить все для босса на большой странице тактического обзора. В качестве технической демонстрации мы добавили конфигурации для 4 боссов Верховного Молота, включая Императора Мар’гока, чтобы вы могли посмотреть, что возможно. Вот краткий обзор основных функций:

    Стеки и графики повреждений.Это показывает, насколько хорошо ваши танки переключаются, чтобы лечить точки стека.

    Рейдовые широкие дебаффы. В данном случае — глупые люди слишком долго простояли в кливе и все умерли в стеке 6. Не делайте этого.

    Шахты на Мар’гоке. Показывает, кто наступил на одного.

    Повреждения, которых можно избежать. Игрок в правом верхнем углу «выигрывает» (данные суммированы по игрокам). Он настроен так, чтобы исключить первое неизбежное случайное попадание и показать только людей, которые не могут двигаться.

    Очевидно, что есть миллиард других комбинаций, которые вы можете построить, но это подойдет для начала — позже вы сможете настроить все и поделиться своими панелями мониторинга с другими людьми.Это не только удобно для проверки выполнения тактики босса, но и что-то вроде сравнения ротации заклинаний между игроками тоже должно быть выполнимым.

    Новые страницы гильдии

    Автор: Майлз 28 ноября 2014 г., 15:30 CET

    Новые страницы гильдий для гильдий, связанных с Battle.net, теперь почти полностью функционируют; на новом сайте вы можете изменить несколько блоков информации, чтобы описать вашу гильдию, статус найма и то, как подать заявку. Мы также работаем над пользовательскими изображениями обложек гильдий, вот небольшой предварительный просмотр того, как может выглядеть ваше.

    Последние изменения — Battle.net, ведение журнала и определение сложности

    Автор: Майлз 28 ноября 2014 г., 14:32 CET

    Мы много работали над обновлением World of Logs для нового пакета расширения и добавлением нескольких основных функций. Конечно, добавлены новые рейдовые инстансы и подземелья, но это еще не все.

    Самое большое изменение — это то, как мы обрабатываем гильдии, миры и аутентификацию. Когда он будет завершен, предпочтительный способ входа в систему — это сделать это с помощью Battle.чистый счет. Это приведет к извлечению ваших гильдий и персонажей из WoW из Blizzard, и вам больше не придется «создавать» гильдию в WoL и самостоятельно обрабатывать участников и разрешения. Подробности этого изменения можно найти на страницах справки. Не стесняйтесь просматривать и отправлять нам отзывы и запросы на добавление функций.

    Есть еще несколько вещей, которые еще не работают для гильдий Battle.net, в первую очередь, подписки. Вы можете продолжать входить в систему и использовать старую систему на данный момент, будет возможность перенести все ваши отчеты и подписку в новую систему, когда она будет готова.

    Второй — это поддержка расширенного формата ведения журнала боевых действий в серверной части. На данный момент это невидимое изменение, используемое только для проверки. Мы запланировали кое-что для этих данных. За дополнительной информацией обратитесь к нам через несколько недель.

    Да, и обнаружение встреч обновлено. Когда-то давно WoW не записывает информацию о встречах в журнал боя, и единственный способ угадать, на какой сложности вы играете, — это посмотреть данные. Если Король-лич вызывает теневые ловушки, это, вероятно, героически; для таких боссов это просто, но было множество исключений, не имеющих дополнительных заклинаний и требующих особого обращения.Теперь с событием ENCOUNTER_START это намного проще; была добавлена ​​поддержка, и все существующие отчеты о трудностях были обновлены, если была загружена достаточно свежая версия WoW. Это работает только для недавних рейдовых зон, поэтому инстансы, такие как Molten Core и инстансы из 5 человек, по-прежнему используют старый код обнаружения skool или не имеют включенного определения сложности. Если есть достаточно интереса, мы можем расширить обнаружение для этих экземпляров, но на данный момент каждый человек в WoD 5 называется «5 нормальных».

    Огненные Недра

    Автор: Майлз 27 ноя 2014 в 17:39 CET

    Огненные Недра добавлено в рейтинговые рейдовые зоны World of Logs! Вы все еще знаете, как обращаться с бомбами Гарра и сыновьями Рагнароса?

    Предварительный просмотр

    Автор: Майлз 12 ноября 2014 г., 18:13 CET

    ,