Подтвердить что ты не робот

Выход консоли Jenkins не в реальном времени

Довольно новый для Дженкинса, и у меня есть простая, но раздражающая проблема. Когда я запускаю работу (Build) на Jenkins, я запускаю команду ruby ​​для выполнения моего теста script.

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

Building in workspace /var/lib/jenkins/workspace/foo_bar
No emails were triggered.
[foo_bar] $ /bin/sh -xe /tmp/hudson4042436272524123595.sh
+ ruby /var/lib/jenkins/test-script.rb

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

Версия Дженкинса: 1.461

4b9b3361

Ответ 1

Чтобы прояснить некоторые ответы.

  • ruby или python или любой разумный язык сценариев будет буферизовать вывод; это необходимо для минимизации IO; запись на диск медленная, запись на консоль медленная...
  • обычно данные получают flush() 'ed автоматически после того, как у вас достаточно данных в буфере со специальной обработкой для строк новой строки. например написав строку без новой строки, тогда sleep() ничего не напишет, пока после завершения sleep() (я использую только sleep в качестве примера, не стесняйтесь заменить любым другим дорогостоящим системным вызовом).

например. это будет ждать 8 секунд, распечатать одну строку, подождать еще 5 секунд, напечатать вторую строку.

from time import sleep

def test():
    print "ok",
    time.sleep(3)
    print "now",
    time.sleep(5)
    print "done"
    time.sleep(5)
    print "again"

test()
  • для ruby, STDOUT.sync = true, включает autoflush; все записи в STDOUT сопровождаются flush(). Это решит вашу проблему, но приведет к большему количеству ввода-вывода.

    STDOUT.sync = true
    
  • для python, вы можете использовать python -u или переменную окружения PYTHONUNBUFFERED, чтобы сделать stdin/stdout/stout не буферизированным, но существуют другие решения которые не меняют stdin или stderr

    export PYTHONUNBUFFERED=1
    
  • для perl, вы autoflush

    autoflush STDOUT 1;
    

Ответ 2

Убедитесь, что ваш script выполняет очистку stdout, stderr. В моем случае у меня была проблема с полировкой, похожая на то, что вы описали, но я использовал python. Следующий код python исправил его для меня:

import sys
sys.stdout.flush()

Я не Ruby-код, но google показывает следующее:

$stdout.flush

Ответ 3

Самое простое решение - включить синхронизирующий буфер для вывода. Что-то, о чем писал @Craig в своем ответе, но одно линейное решение, которое будет охватывать целый script, и не требует многократно буферизации буфера.

Просто напишите

STDOUT.sync = true

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

STDOUT.sync = false

Это решение Ruby для c.

Ответ 4

Мне кажется, что python -u работает.

например. В пакетной команде

python -u foo.py

Ответ 5

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

https://unix.stackexchange.com/a/25378

Вы можете использовать stdbuf для изменения поведения буферизации для любой программы.

В моем случае я выводил вывод из оболочки script через tee и grep для разделения строк на консоль или файл на основе содержимого. Консоль висела, как описано OP. Это решило это:

./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | stdbuf -oL -eL grep LOG:

В конце концов я обнаружил, что могу просто передать --line-buffered в grep для того же результата:

./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | grep --line-buffered LOG:

Ответ 6

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

Другая вещь, о которой нужно помнить, заключается в том, что сам Дженкинс выполняет линейную буферизацию. Если у вас медленный процесс, который испускает одиночные символы (например, сводка тестового набора nunit, которая печатает . для успешного теста и E для ошибки), вы ничего не увидите до конца строки.

[Истина для моего Jenkins 1.572, работающего в окне Windows.]

Ответ 7

Операционная система выполняет буферизацию выходных данных по своей природе, чтобы сохранить CPU, а также Дженкинс.

Похоже, вы используете команду shell для запуска Ruby script -
Я предлагаю запустить Ruby script напрямую через выделенный плагин:

Плагин Jenkins Ruby

(возможно, потребуется его установить)