Выход консоли 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
Ответы
Ответ 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
(возможно, потребуется его установить)