22 August 2013

Что такое Fabric?

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

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

Intro

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

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

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

Ближе к делу

Я написал команду на fabric, которая позволяет читать логи с нескольких серверов в режиме реального времени.

    from fabric.api import env, task, sudo, settings    
    
    env.roledefs = {
        # production server
        'www': ['www1.example.ru', 'www2.example.ru']
    }
        
    env.remote_interrupt = True
    env.LOG = '<path_to_log>'
        
    @task
    def log():
        assert(env.remote_interrupt == True)
        with settings(warn_only=True):
            sudo("tail -n 50 -f " + env.LOG)
    

Убедитесь, что env.remote_interrupt == True, иначе Ctrl-C не будет останавливать tail -f на удаленном сервере и эта команда зависнет там навсегда. Прибить её можно будет через:

sudo kill -9 `ps aux | grep tail | awk '{print $2}'`

Вот и все, теперь осталось запустить команду log на всех серверах сразу, для этого существует параметр –parallel:

fab -R www --parallel log

В дополнение в параметру командной строки, в fabric существует декоратор @parallel, который выполняет ту же роль:

    @parallel
    def log():
        assert(env.remote_interrupt == True)
        with settings(warn_only=True):
            sudo("tail -n 50 -f " + env.LOG)

В этом случае, консольная команда немного упростится:

fab -R www log

Данный рецепт для fabric можно скачать здесь.



blog comments powered by Disqus

Fork me on GitHub