2012-07-24 34 views
29

詹金斯很新,我有一個簡單而煩人的問題。當我在Jenkins上運行Job(Build)時,我觸發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 

基本上它掛在這個輸出,直到構建完成比它只顯示完整的輸出。有趣的是,這不是一致的行爲,有時它應該如此。但大多數情況下沒有實時控制檯輸出。

詹金斯版本:1.461

+0

多麼強大的服務器正在運行並沒有這個腳本需要多長時間才能執行?這聽起來像是由於服務器超載導致的延遲。當我的詹金斯大師滿負荷運轉時,我看到了類似的症狀。 – CIGuy 2012-07-24 15:22:07

+0

感謝您的興趣,這實際上是有道理的。在這種情況下,我們正在討論EC2實例'small',http://aws.amazon.com/ec2/instance-types/,但它只是進程運行。難道你需要的不僅僅是這些? – 2012-09-17 08:03:00

+0

這取決於有多少個作業正在運行,但是,如果同時在一個小實例上運行多個作業,我希望看到延遲。 – CIGuy 2012-09-17 15:21:51

回答

38

澄清一些答案。

  • rubypython或任何明智的腳本語言將緩衝輸出;這是爲了儘量減少IO;寫入磁盤速度慢,寫入控制檯速度較慢...
  • 通常在緩衝區中有足夠的數據並對新行進行特殊處理後,會自動編輯flush()'。例如寫一個沒有換行的字符串,然後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() 
  • rubySTDOUT.sync = true,接通autoflush上;所有寫入STDOUT後跟flush()。這將解決您的問題,但會導致更多的IO。

    STDOUT.sync = true 
    
  • python,您可以使用python -u或環境變量PYTHONUNBUFFERED,使stdin/stdout/stout沒有緩衝,但there are other solutions不爲perl改變stdinstderr

    export PYTHONUNBUFFERED=1 
    
  • ,你有autoflush

    autoflush STDOUT 1; 
    
0

該操作系統被自然緩衝輸出數據,爲了節省CPU,也是如此詹金斯。

看起來你正在使用一個shell命令來運行Ruby腳本 -
我建議通過專門的插件沒有直接運行Ruby腳本:

Jenkins Ruby Plugin

(可能需要安裝)

+0

我會試試這個,需要一些時間。謝謝。 – 2012-07-25 08:19:15

+0

你好,這是行不通的(試了相同的結果,因爲解決方案並不是很實用,因爲ruby代碼保存在Jenkins的工作中,版本更難以這樣做 – 2012-07-26 09:10:39

+1

我同意「非源代碼控制「該解決方案的性質 - 最好是在Jenkins之外管理任何腳本,並且只從工作中調用它(對於Jenkins中的shell /批處理塊也是如此) – Gonen 2012-07-26 09:48:07

8

確保您的腳本正在刷新它的標準輸出stderr。 在我的情況下,我有一個類似於你描述的拋光問題,但我使用的是python。 以下代碼定爲我的蟒蛇:

import sys 
sys.stdout.flush() 

我不是一個Ruby代碼,但谷歌揭示了以下內容:

$stdout.flush 
+0

嗨,Craig感謝您回答'STDOUT.flush ''或'$ stdout.flush'就可以工作了。問題是你需要把這些命令中的很多通過腳本清空緩衝區,需要的時候我會發布基本上包含同步緩衝區刷新到輸出的解決方案 – 2012-10-19 12:06:49

+0

謝謝,它真的解決了我的問題,因爲它在沒有刷新的shell下運行良好,因此我沒有考慮它。 – 2013-05-18 14:46:42

4

最簡單的解決方案在這裏是開啓同步緩衝輸出。 @Craig在他的回答中寫了一些內容,但一行解決方案將覆蓋整個腳本,而不需要多次刷新緩衝區。

剛寫

STDOUT.sync = true 

邏輯後面簡單,避免使用IO操作多次輸出進行緩衝。禁用此功能

STDOUT.sync = false 

這是Ruby解決方案ofc。

2

在我看來,python -u也適用。

E.g.批量命令

python -u foo.py 
1

每一個其他的答案是具體到某個程序或其他,但我發現一個更通用的解決方案在這裏:

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

您可以使用stdbuf更改任何程序的緩衝行爲。

在我的情況下,我通過teegrep從shell腳本中輸出管道,將行分成控制檯或基於內容的文件。控制檯按照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: 
1

其他的答案是正確的說,你需要確保標準輸出不會被緩衝。

要注意的另一件事是詹金斯本身一行一行地緩衝。如果運行緩慢的進程發出單個字符(例如,nunit測試套件摘要爲成功測試打印.,錯誤爲E),直到行尾纔會看到任何內容。

[真我詹金斯1.572 Windows設備上運行。]