การดีบัก: เอาต์พุตคอนโซลและสคริปต์พุ่งพรวด


16

คุณจะส่งเอาต์พุตของสคริปต์ upstart ไปยังเทอร์มินัลเพื่อค้นหาการติดตามกลับในโค้ดไพ ธ อนได้อย่างไร ฉันใช้เวลาตลอดไปในการทำสิ่งต่าง ๆ โดยไม่มีร่องรอยการย้อนกลับที่เคยใช้เวลาเพียงวินาทีเดียว ฉันต้องโทรออกหลาย ๆ ไฟล์เพื่อติดตามข้อผิดพลาด สิ่งที่ใช้เวลาสองวินาทีในการค้นหาก่อนด้วยการย้อนกลับคือการเปลี่ยนไปใช้เวลาหลายนาที นี่คือความสุข สิ่งนี้ได้เกิดขึ้นสองสามสัปดาห์แล้วและฉันก็เบื่อมัน บางคนจะพูดในเรื่องนี้ได้โปรด ฉันรู้สึกเหมือนฉันกำลังใช้แอสเซมบลีโดยไม่มีดีบักเกอร์อีกครั้ง

คำตอบ:


27

หากคุณใช้ Upstart 1.4 หรือใหม่กว่าให้ใส่console logงาน Upstart ของคุณและเอาต์พุตทั้งหมดไปยัง stdout / stderr จะจบลง/var/log/upstart/<job>.logด้วยการ จากนั้นคุณสามารถทำได้tail -f /var/log/upstart/<job>.log &เพื่อให้เอาต์พุตปรากฏในเทอร์มินัล


สายไปงานปาร์ตี้ แต่คำตอบนี้ช่วยฉัน :) นอกจากนี้ดูเหมือนว่างานนี้สำหรับฉันโดยไม่ต้องตั้งค่าพิเศษใด ๆ ในไฟล์ conf พุ่งพรวด สำหรับส่วนของฉันนี้ควรเป็นคำตอบที่ยอมรับ
rslite

ไม่ทราบว่าบันทึกการบริการที่ได้รับการจัดการพุ่งพรวดเข้ามา/var/log/upstartแล้ว มีประโยชน์จริงๆขอบคุณ
ฟรานซิสโก

2

มีทั้งส่วนเกี่ยวกับเทคนิคการแก้จุดบกพร่องในเรื่องพุ่งพรวดตำรา สิ่งที่ง่ายที่สุดที่คุณสามารถทำได้คือเพิ่ม--debugไปยังอาร์กิวเมนต์เคอร์เนลของคุณซึ่งจะเพิ่มความฟุ้งซ่านของคนธรรมดาและทิ้งทุกอย่างลงใน syslog ใช่การแก้ไขข้อบกพร่องนั้นซับซ้อนมันเป็นภาพสะท้อนของความซับซ้อนสุทธิที่จำเป็นในการสร้างระบบ init แบบขนาน ฉันแน่ใจว่ามีห้องพักสำหรับการปรับปรุง


2
หนังสือทำอาหารไม่ได้อธิบายสภาพแวดล้อมการแก้จุดบกพร่องให้กับผู้มาใหม่อย่างถูกต้อง ฉันเคยเห็นคำอธิบายที่คล้ายกันมาก่อน มีทั้งที่ขาดหรือตั้งสมมติฐาน มันน่าผิดหวังมากสำหรับคนที่ต้องการเพิ่มในชุมชนและเพิ่งเริ่มต้น ฉันไม่เคยวิ่งเข้าไปในสภาพแวดล้อมการเขียนโปรแกรมที่ไม่ได้ระบุบรรทัดของรหัสที่ข้อผิดพลาดเกิดขึ้นยกเว้นในการชุมนุมที่คุณกำลัง reinventing ล้อเพื่อที่จะได้รับการอภัย
bambuntu

คุณจะแนะนำอะไรดี มันเป็นเอกสารเปิด หากคุณมีเทคนิคการแก้ไขข้อบกพร่องที่มี leaps และขอบเขตด้านบนแสดงสิ่งที่มีอยู่แล้วโปรดเพิ่ม ปัญหาของ OP เป็นผลมาจากการไม่เข้าใจวิธีการจัดการกระบวนทัศน์พื้นฐานของยูนิกซ์ในรันไทม์เพิ่มเติมของตัวเลือกและบริบทที่กำลังถูกปรับใช้เนื่องจากคุณใช้ python หรือ [แทรกภาษารันไทม์แฟนซีที่นี่] ไม่ได้หมายความว่าคุณ ได้รับการละเว้นรันไทม์พื้นฐาน UNIX
ppetraki

2

เมื่อฉันเขียน python daemon ฉันจะตรวจจับข้อยกเว้นทั้งหมดแล้วโยนไปยังล็อกไฟล์ ฉันไม่เพียง แต่ใช้สำหรับการแก้ไขข้อบกพร่อง แต่ในการผลิตด้วย ฉันมีสคริปเล็ก ๆ ที่ฉันวิ่งทุกเช้าซึ่งมองหาบางสิ่งที่ไม่ดีในบันทึก

นอกจากนี้ยังช่วยในการทำให้ daemon ทำงานได้อย่างแน่นอน

โค้ดตัวอย่างบางส่วน (ฉันลบส่วนที่ไม่น่าสนใจ):

import logging

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename=LOG_FILE,
                    filemode='w')
    logging.info("Sincrod inicializado")
    if not DEBUG:
        daemonize()
    while True:
        try:
            actua()
        except:
            logging.error(sys.exc_info())
        if (datetime.datetime.now().hour > NOITE_EMPEZA\
         and datetime.datetime.now().hour < NOITE_REMATA):
            time.sleep(INTERVALO_NOITE)
        else:
            time.sleep(INTERVALO_DIA)

โดยที่ actua () เป็นภูตจริง (มันเขียนไว้ในบันทึกด้วย) โปรดทราบว่าฉันมีตัวแปร DEBUG ในไฟล์การตั้งค่าเมื่อเป็น True ฉันไม่แยก daemon ดังนั้นจึงเรียกใช้งานบนคอนโซล

ภูต

Daemons เทียบเท่ายูนิกซ์กับบริการ windows พวกเขาเป็นกระบวนการที่ทำงานในพื้นหลังเป็นอิสระจากกระบวนการอื่น ๆ นั่นหมายความว่าพ่อของพวกเขามักจะประทับจิตและพวกเขาถูกแยกออกจาก tty เนื่องจากเป็นอิสระจึงไม่มีตำแหน่งที่กำหนดไว้ล่วงหน้าสำหรับการแสดงผล

มีไพ ธ อนไลบรารีและตัวอย่างจำนวนมากเพื่อสร้างดีมอนในตัวอย่างข้างต้นฉันใช้ฟังก์ชั่นของตัวเองซึ่งผสมผสานแนวคิดบางอย่างจาก Steinar Knutsens และ Jeff Kunces มันเป็นง่ายๆเป็นไปได้ทราบว่าผมแยกเป็นสองเท่า

def daemonize():
    """Forks this process creating a daemon and killing the original one"""
    if (not os.fork()):
        # get our own session and fixup std[in,out,err]
        os.setsid()
        sys.stdin.close()
        sys.stdout = NullDevice()
        sys.stderr = NullDevice()
        if (not os.fork()):
            # hang around till adopted by init
            ppid = os.getppid()
            while (ppid != 1):
                time.sleep(0.5)
                ppid = os.getppid()
        else:
            # time for child to die
            os._exit(0)
    else:
        # wait for child to die and then bail
        os.wait()
        sys.exit()

ก็โอเค เนื่องจากคุณได้เข้าสู่ระบบ syslog แล้วเพียงกรองข้อความ daemon ของคุณและทิ้งไปยังคอนโซล ฉันไม่เห็นว่าทำไมถึงเป็นเรื่องธรรมดาโดยเฉพาะ? SysV init จะมีปัญหาเดียวกัน
ppetraki

คุณพูดถูกมันไม่ใช่เฉพาะการพุ่งพรวดเพื่อบอกความจริงว่าเซิร์ฟเวอร์ของฉันส่วนใหญ่รัน 8.04 ไม่พุ่งพรวด แต่มันก็ใช้ได้สำหรับการพุ่งพรวดเช่นกัน OP ได้ถามถึงวิธีการดีบักสคริปต์หลามด้วยการพุ่งพรวดไม่ใช่สำหรับวิธีการที่ทำงานร่วมกับการพุ่งพรวดเท่านั้น ฉันไม่ได้เข้าสู่ระบบ syslog แต่ไปยังไฟล์ที่เฉพาะเจาะจงและ 'เคล็ดลับ' ที่นี่กำลังจับข้อยกเว้นทั้งหมดและทิ้งการติดตามสแต็คไปยังไฟล์นั้น
Javier Rivera

นั่นเป็นเพียงการจัดการ stdout ตามบริบทใช่มั้ย ฉันรู้ว่ายูนิกซ์ daemons มากมายที่มีความสามารถในการบันทึกที่เทียบเท่าไม่ว่ามันจะแนบกับ tty หรือทำงานเป็น daemon ถ้านี่เป็น Ruby ฉันจะขับรถเกินหรือตกแต่งวิธีการเรียนพื้นฐานที่ข้อยกเว้นใช้ในการแสดงผล ฉันแน่ใจว่าสิ่งที่คล้ายกันสามารถทำได้ใน Python คุณอาจตอบคำถามได้ดีกว่าเกี่ยวกับการแลกเปลี่ยนสแต็คที่เหมาะสม นี่เป็นปัญหาพื้นฐานเกี่ยวกับการเขียนรหัส / การออกแบบ daemon unix มากกว่าและตามที่คุณระบุไว้มันไม่มีอะไรพิเศษเกี่ยวกับสคริปต์เริ่มต้น
ppetraki

ฉันยังคงคุ้นเคยกับศัพท์แสง ฉันถือว่า daemon คุณหมายถึงสคริปต์เฉพาะที่ทำงานในพื้นหลัง ในรหัสของคุณฉันเพิ่งวางสคริปต์ของฉันแทนที่ actua () เพื่อรับการเรียกกลับสำหรับการโทรสคริปต์นั้น มีช่องทางไปยังคอนโซลแทนไฟล์หรือไม่?
bambuntu

1
daemons ในแบบสแตนด์อะโลนมักจะถูกแยกออกจาก tty ที่พวกเขาเริ่มต้นขึ้นได้ปิดการจัดการไฟล์ดั้งเดิมของพวกเขาไปยัง stdin, stdout และ stdin และเป็นลูกของ init ดังนั้นหากคุณต้องการพิมพ์ข้อยกเว้นไปยังสถานที่ที่เฉพาะเจาะจงค้นหาวิธีที่พวกเขาจะถูกส่งออกและนำพวกเขาจากที่นั่น linfo.org/daemon.html อีกครั้งนี้ไม่มีอะไรเกี่ยวข้องกับการพุ่งพรวดหรือแม้แต่เริ่มต้นสำหรับเรื่องนั้น ทำให้โปรแกรมของคุณทำงานได้อย่างถูกต้องในโหมด daemon ที่แท้จริงแล้วเลื่อนขึ้นไปข้างบน
ppetraki
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.