2012-07-24 16 views
29

जेनकींस के लिए बिल्कुल नया और मुझे सरल लेकिन परेशानी की समस्या है। जब मैं जेनकींस पर नौकरी (बिल्ड) चलाता हूं तो मैं अपनी टेस्ट स्क्रिप्ट निष्पादित करने के लिए रूबी कमांड को ट्रिगर कर रहा हूं।जेनकींस कंसोल आउटपुट रीयलटाइम में नहीं

समस्या यह है कि जेनकींस कंसोल से वास्तविक समय में आउटपुट प्रदर्शित नहीं कर रहा है। ट्रिगर लॉग यहाँ है।

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

+0

रुचियों के लिए धन्यवाद, जो वास्तव में समझ में आता है। इस मामले में हम ईसी 2 इंस्टेंस 'छोटे', http://aws.amazon.com/ec2/instance-types/ के बारे में बात कर रहे हैं, लेकिन यह केवल प्रक्रिया चल रही है। क्या आपको इससे ज्यादा आवश्यकता हो सकती है? –

+0

यह निर्भर करता है कि कितनी नौकरियां चल रही हैं, लेकिन हां, यदि आप एक छोटी घटना पर एक साथ कुछ नौकरियां चल रहे हैं तो मुझे देरी दिखाई देगी। – CIGuy

उत्तर

38

कुछ उत्तरों को स्पष्ट करने के लिए।

  • ruby या python या किसी समझदार पटकथा भाषा उत्पादन बफ़र जाएगा; आईओ को कम करने के लिए यह है; डिस्क पर लिखना धीमा है, कंसोल पर लिखना धीमा है ...
  • आम तौर पर डेटा को 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() 
  • ruby, STDOUT.sync = true के लिए

    , बदल जाता है autoflush पर; सभी STDOUT पर लिखते हैं flush() के बाद। यह आपकी समस्या का समाधान करेगा लेकिन परिणामस्वरूप आईओ में अधिक परिणाम होगा।

    STDOUT.sync = true 
    
  • python के लिए, आप stdin/stdout/stout बफ़र नहीं बनाने के लिए python -u या वातावरण चर PYTHONUNBUFFERED उपयोग कर सकते हैं, लेकिन there are other solutions कि perl के लिए stdin या stderr

    export PYTHONUNBUFFERED=1 
    
  • में परिवर्तन नहीं करते हैं, तो आप autoflush

    है
    autoflush STDOUT 1; 
    
0

ऑपरेटिंग सिस्टम सीपीयू को बचाने के लिए प्रकृति द्वारा उत्पादन-डेटा बफरिंग है, है, और इसलिए जेनकींस करता है।

लगता है आप अपने रूबी स्क्रिप्ट चलाने के लिए एक खोल-आदेश का उपयोग कर रहे हैं -
मैं समर्पित प्लग इन के माध्यम से सीधे अपने रूबी स्क्रिप्ट चलाने का सुझाव:

Jenkins Ruby Plugin

(यह स्थापित करने की आवश्यकता हो सकती है)

+0

मैं इसे आजमाउंगा, इसमें कुछ समय लगेगा। धन्यवाद। –

+0

हैलो, यह काम नहीं कर रहा है :(इसे एक ही परिणाम का प्रयास किया। साथ ही समाधान बहुत व्यावहारिक नहीं है क्योंकि रूबी कोड जेनकिन्स जॉब में सहेजा गया है, संस्करण-आईएनजी बहुत कठिन है। –

+1

मैं "स्रोत-नियंत्रण" के बारे में सहमत हूं "उस समाधान की प्रकृति - जेनकींस के बाहर किसी भी स्क्रिप्ट को प्रबंधित करना बेहतर है, और इसे केवल नौकरी से बुलाएं। (जेनकिंस में भी खोल/बैच ब्लॉक के लिए सच) – Gonen

8

सुनिश्चित करें कि आपकी स्क्रिप्ट इसे stdout, stderr flushing है। मेरे मामले में मेरे पास आपके द्वारा वर्णित एक बफिंग समस्या थी लेकिन मैं अजगर का उपयोग कर रहा था। अजगर निम्नलिखित कोड मेरे लिए यह तय:

import sys 
sys.stdout.flush() 

मैं एक रूबी कोड नहीं कर रहा हूँ, लेकिन गूगल का पता चलता है निम्नलिखित:

$stdout.flush 
+0

हाय, क्रेग उत्तर के लिए धन्यवाद 'STDOUT.flush 'या' $ stdout.flush' काम करेगा। समस्या यह है कि आपको आवश्यकता होने पर बफर को फ्लश करने के लिए इनमें से कई आदेशों को स्क्रिप्ट से बाहर निकालना होगा। मैं समाधान पोस्ट करूंगा जो मूल रूप से आउटपुट में सिंक किए गए बफर फ्लश को कवर करता है। –

+0

धन्यवाद, यह वास्तव में मेरी समस्या हल हो गई, क्योंकि यह फ्लश के बिना खोल के नीचे अच्छी तरह से काम करता है, इसलिए मैंने इसके बारे में नहीं सोचा। –

4

सबसे आसान यहाँ समाधान उत्पादन के लिए बफर सिंक करना चालू करने के लिए है। कुछ ऐसा जो @ क्रैग ने अपने जवाब में लिखा था, लेकिन एक लाइन समाधान जो पूरी लिपि को कवर करेगा, और आपको कई बार बफर फ्लश करने की आवश्यकता नहीं है।

बस लिखने

STDOUT.sync = true 

तर्क के पीछे सरल है, आईओ आपरेशन कई बार उत्पादन बफ़र का उपयोग कर से बचने के लिए। इस उपयोग को अक्षम करने के लिए

STDOUT.sync = false 

यह रूबी समाधान का है।

2

ऐसा लगता है कि python -u भी काम करता है।

उदा। बैच कमांड

python -u foo.py 
1

अन्य उत्तर में से हर एक कार्यक्रम से या किसी अन्य के लिए विशिष्ट है, लेकिन मैं यहाँ एक अधिक सामान्य समाधान नहीं मिला:

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

आप stdbuf उपयोग कर सकते हैं किसी भी कार्यक्रम की प्रतिरोधक व्यवहार में परिवर्तन करने के लिए।

मेरे मामले में, मैं tee और grep के माध्यम से शेल स्क्रिप्ट से आउटपुट पाइप कर रहा था ताकि कंसोल या सामग्री के आधार पर फ़ाइल को विभाजित किया जा सके। ओएस द्वारा वर्णित कंसोल लटक रहा था। यह इसे हल:

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

अन्य उत्तर कह रही है कि आप मानक आउटपुट सुनिश्चित करने की आवश्यकता नहीं है बफ़र में सही कर रहे हैं:

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

अंततः मैं मैं सिर्फ गुजारें सकता --line-buffered एक ही परिणाम के लिए grep के लिए खोज की ।

दूसरी बात यह जानना है कि जेनकिंस स्वयं लाइन बफरिंग द्वारा लाइन करता है। यदि आपके पास धीमी गति से चलने वाली प्रक्रिया है जो एकल वर्णों को उत्सर्जित करती है (उदाहरण के लिए, एक नुनिट टेस्ट सूट सारांश जो एक सफल परीक्षण के लिए . प्रिंट करता है और किसी त्रुटि के लिए E) आपको लाइन के अंत तक कुछ भी दिखाई नहीं देगा।

[के लिए मेरे जेनकींस 1.572 सच है एक Windows बॉक्स पर चल रहा है।]