Используем Graylog с Perl

Tags:

Устанавливаем Graylog. Для опытов я использовал преднастроенную VM для VirtualBox http://docs.graylog.org/en/1.0/pages/installation.html#virtual-machine-appliances

! На момент написания статьи в VM идет версия Graylog-web с багом - при создании dashboard на нее нельзя добавить виджет т.к. JS-скрипт ответственный за разблокировку dashboard падает с ошибкой. Что-бы что-то сделать с дэшбордом на него надо добавить любой виджет с любой страницы. Это делается по клику на иконку возле названия виджета и выбором нужного дэшборда.

Первым делом надо создать Input для логов. Мы будем использовать GELF формат через Log::Log4perl. Идем System->Inputs в выпадающем списке выбираем GELF UDP и жмем Launch Input. В открывшемся окне выбираем ноды на которых будет работать этот инпут, описание, адрес на котором он будет слушать. Жмем launch, убеждаемся что он стартанул и на этом пока все работы с Graylog закончены.

Теперь устанавливаем пакет Log::Log4perl::Layout::GELF.

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

log4perl.logger.graylog                     = INFO, Screen, Graylog

log4perl.appender.Screen                = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr         = 0
log4perl.appender.Screen.layout         = Log::Log4perl::Layout::PatternLayout
log4perl.appender.Screen.layout.ConversionPattern = [%d] [%p] %m%n
log4perl.appender.Screen.utf8           = 1

log4perl.appender.Graylog          = Log::Log4perl::Appender::Socket
log4perl.appender.Graylog.PeerAddr = graylog.host
log4perl.appender.Graylog.PeerPort = 12201
log4perl.appender.Graylog.Proto    = udp
log4perl.appender.Graylog.layout   = GELF

Создаем тестовый скрипт:

#!/usr/bin/env perl

use utf8;
use strict;
use Log::Log4perl;

#Загружаем конфигурацию 
Log::Log4perl::init('logger.conf');

#Получаем логгер
my $logger = Log::Log4perl->get_logger('graylog');

$logger->info('hello graylog');
$logger->info('Тестовое сообщение UTF8');

В теории, этого достаточно для того что бы нужные логи вашего приложения начали идти в Graylog. Но, как обычно, есть нюанс - этот модуль совершенно не представляет что есть более чем однобайтные кодировки и при попытке что-то записать в лог что-то с utf8 мы получим ошибку Wide character in IO::Compress::Gzip::write и в Graylog сообщение не придет.

Для обычных аппендеров, например Screen, эта проблема решается просто - дописываем в конфигурацию флаг включения utf8:

log4perl.appender.FileAppndr.utf8     = 1

Но в данном случае проблема на уровне layout и этот модуль не обрабатывает такую ситуацию.

Для себя я эту проблему решил просто - сделал форк модуля с названием GELFUtf и использую его.

Таким образом в конфиге вместо log4perl.appender.Graylog.layout = GELF пишу log4perl.appender.Graylog.layout = GELFUtf.

Подменить фунцию на лету у меня не получилось, скорее всего из-за хитрой архитектуры Log4perl. А лезть патчить в рантайм - овчинка выделки не стоит. Так что пока пользуюсь патченым модулем и коплю силы на создание полноценного патча для оригинального модуля.

stdout autoflush

Tags:

Классический метод:

$oldfh = select(STDERR); $| = 1; select($oldfh);

ООП:

use IO::Handle;
STDERR->autoflush(1);

Ubuntu 14.04 + Gearman

Tags:

В базовой установке Gearman в ubuntu 14.04 есть баг - инит-скрипт написан не правильно и в результате Gearman не реагирует наличие конфиг файла и запускается с настойками по умолчанию. Причем, на одном из серверов у меня проблемма после обновления усугубилась и он перестал запускаться даже с настройками по умолчанию.

Есть два варианта решения проблемы:

  1. Пропатчить инит-скрипт, как это сделать можно прочитать здесь
  2. Запускать его из под supervisord.

У меня все приложения крутятся под supervisor, так что я пошел этим путем.

Минимальный конфиг файл для супервизора:

[program:gearmand]
command=/usr/sbin/gearmand -L 127.0.0.1 --user=gearman --log-file=stderr
autorestart=true
autostart=true

-L 127.0.0.1 указано, во первых, что-бы gearman не биндился на внешние интерфейсы (там все закрыто фаирволом, но все же). Во вторых - если на машине включен ipv6, но не настроен, то gearman будет пытаться забиндиться и на ipv6 и падать.

З.Ы. инит для supervisord в 14.04 тоже кривой, но это уже другая история.

Starting with Rex

Tags:

В жизни каждого человека настает момент когда ему становится лениво делать одно и то же на удаленных серверах и хочется автоматизации.

В решении этой тяжелой жизненной проблемы нам поможет R(?)ex.

Небольшой F.A.Q

Что это?

Это приложение для управления удаленными(и не очень) серверами и приложениями.

Я могу просто написать bash/perl/pithon/ruby/etc-скрипт и он сделает то же самое.

Несомненно, но это будет очередное изобретение велосипеда с колесами разной степеньи квадратности.

Почему не Puppet/Ansible?

Потому что здесь про Perl, но сравнение Rex и Ansible я еще сделаю.

Поехали

Во первых, Rex можно использовать для простого запуска команд на удаленном сервере:

rex -H "example.com example.ru" -e "say run 'uptime'"

Задачи выполняются последовательно, так что придется подождать пока опросятся все сервера, особенно если их много.

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

По умолчанию Rex использует файл под названием Rexfile (удивительное совпадение).

Попробуем сделать что-то полезное.

Создадим Rexfile который будет содержать команду deploy. По этой команде Rex пойдет на удаленный сервер и сделает там git pull для сайта. Простейшний вариант деплоя.

 use Rex -feature => ['1.0'];

 user "myuser";
 private_key "/home/myuser/.ssh/id_rsa";
 public_key "/home/myuser/.ssh/id_rsa.pub";
 key_auth;

 group myservers => "example.ru";

 desc "Deploy the blog on example.ru";
 task "deploy", group => "myservers", sub {
   run "cd /srv/www/example.ru && git pull origin gh-pages";
 };

Теперь можно сказать: rex deploy

Дальше Rex залогинится под пользователем "myuser" с использованием указанных ключей и выполнит команду указанную в опции run. Если пользователь на удаленном сервер совпадает с текущим - то первую секцию можно опустить. Будет использоваться текущий пользователь и его настройки ключей для ssh. Но если планируется использование команды через cron - то указывать надо обязательно, иначе ничего работать не будет.

Так же можно обновлять конфигурацию копируя на хосты необходимые файлы (вы же не храните авторизационные данные в Git, правда?) приведем содержимое раздела task к виду:

 run "cd /srv/www/example.ru && git pull origin gh-pages";
 file "/srv/www/example.ru/test.conf",
     source    => "files/test.conf";

Теперь при выполнении rex deploy будет выполнен pull из репозитория на удаленном сервере, а затем туда будет скопирован файл files/test.conf.

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

А те кому не хочется ждать - могут почитать официальную документацию, она весьма подробная и с хорошими примерами.

Ubuntu LC_ALL = (unset)

Tags:

При установке Ubuntu (в основном на VDS) периодический вылезает ошибка:

LANGUAGE = (unset)
LC_ALL = (unset)

Для исправления делаем:

# echo LC_ALL="ru_RU.UTF-8" >> /etc/environment
# echo LC_CTYPE="ru_RU.UTF-8" >> /etc/environment
# locale-gen ru_RU.UTF-8

И перелегониваемся.

Яндекс.Метрика