48

Jenkinsはかなり新しいので、単純ですが厄介な問題があります。Jenkinsでジョブ(ビルド)を実行すると、rubyコマンドをトリガーしてテストスクリプトを実行します。

問題は、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

基本的に、完全な出力を表示するだけでなく、ビルドが完了するまでこの出力でハングします。面白いことに、これは一貫した動作ではなく、正常に動作する場合もあります。ただし、ほとんどの場合、リアルタイムのコンソール出力はありません。

Jenkinsバージョン:1.461

4

9 に答える 9

70

いくつかの答えを明確にするため。

  • rubyまたは、pythonまたは適切なスクリプト言語が出力をバッファリングします。これは、IOを最小化するためです。ディスクへの書き込みが遅く、コンソールへの書き込みが遅い...
  • 通常、データはflush()、改行用の特別な処理を備えた十分なデータがバッファにあると、自動的に取得されます。たとえば、改行なしで文字列をsleep()書き込むと、が完了するまで何も書き込まれませんsleep()(私はsleep例としてのみ使用していますが、他の高価なシステムコールに置き換えてください)。

たとえば、これは8秒待機し、1行を印刷し、さらに5秒待機し、2行目を印刷します。

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()ます。これで問題は解決しますが、IOが増えます。

    STDOUT.sync = true
    
  • の場合、または環境変数をpython使用してバッファリングしないようにすることができますが、変更されない、または変更されない他のソリューションがあります。python -uPYTHONUNBUFFEREDstdin/stdout/stoutstdinstderr

    export PYTHONUNBUFFERED=1
    
  • のためperlに、あなたは持っていますautoflush

    autoflush STDOUT 1;
    
于 2014-01-21T19:44:55.200 に答える
13

スクリプトがstdoutとstderrをフラッシュしていることを確認してください。私の場合、あなたが説明したのと同様のバッファリングの問題がありましたが、Pythonを使用していました。次のPythonコードは私のためにそれを修正しました:

import sys
sys.stdout.flush()

私はRubyコーダーではありませんが、Googleは次のことを明らかにしています。

$stdout.flush
于 2012-10-19T11:43:16.700 に答える
8

それpython -uもうまくいくように私には思えます。

例:バッチコマンド

python -u foo.py
于 2014-01-21T00:22:08.040 に答える
4

ここでの最も簡単な解決策は、出力への同期バッファをオンにすることです。@Craigが彼の回答で書いたものですが、スクリプト全体をカバーし、バッファを何度もフラッシュする必要がない1行のソリューションです。

書くだけ

STDOUT.sync = true

背後にあるロジックは単純で、出力がバッファリングされる回数が多いIO操作の使用を回避します。この使用を無効にするには

STDOUT.sync = false

これはRubyソリューションofcです。

于 2012-10-19T12:10:49.353 に答える
3

他のそれぞれの答えは、あるプログラムまたは別のプログラムに固有ですが、私はここでより一般的な解決策を見つけました:

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

を使用stdbufして、任意のプログラムのバッファリング動作を変更できます。

私の場合、シェルスクリプトからの出力をパイプでつなぎ、teegrepをコンソールまたはコンテンツに基づいてファイルに分割していました。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:
于 2014-10-11T02:39:05.717 に答える
3

他の答えは、標準出力がバッファリングされていないことを確認する必要があるという点で正しいです。

注意すべきもう1つの点は、Jenkins自体が行ごとのバッファリングを行うことです。.単一文字を出力する実行速度の遅いプロセスがある場合(たとえば、テストが成功した場合とエラーがあった場合にを出力するnunitテストスイートの要約E)、行の終わりまで何も表示されません。

[Windowsボックスで実行されている私のJenkins1.572に当てはまります。]

于 2015-07-08T08:36:27.170 に答える
1

一部のコマンドでteeは、バッファリングを解除するための最良の選択を含めて、パッケージunbufferから呼び出されるプログラムがあります。expect

使用例:

それ以外の

somecommand | tee /some/path

行う

somecommand | unbuffer -p tee /some/path

ソースと詳細情報:

于 2018-10-09T18:30:50.027 に答える
0

オペレーティングシステムは、CPUを節約するために、本質的に出力データをバッファリングしています。Jenkinsも同様です。

シェルコマンドを使用してRubyスクリプトを実行しているようです-
専用プラグインを介してRubyスクリプトを直接実行することをお勧めします。

JenkinsRubyプラグイン

(インストールする必要があるかもしれません)

于 2012-07-24T20:41:27.213 に答える
0

Pythonは出力トレースをバッファリングし、スクリプトの最後に出力して、コンソールへの書き込みが遅いため、コンソールへの書き込みを最小限に抑えます。

トレースの後に次のコマンドを使用できます。そのコマンドの前にキューに入れられているコンソールにすべてのトレースをフラッシュします。

sys.stdout.flush()

于 2019-04-23T14:06:38.150 に答える