Debugging: Output Konsol dan Skrip pemula

16

Bagaimana Anda mengirim output skrip pemula ke terminal sehingga menemukan traceback dalam kode python? Butuh waktu lama bagiku untuk melakukan hal-hal tanpa jejak yang dulu hanya butuh satu detik. Saya harus melakukan beberapa panggilan tulis file untuk melacak kesalahan. Apa yang dibutuhkan kedua untuk ditemukan sebelumnya dengan traceback berubah menjadi beberapa menit menit. Ini menyedihkan. Ini telah berlangsung selama beberapa minggu sekarang dan saya muak. tolong ada yang angkat bicara tentang ini. Saya merasa seperti menggunakan perakitan tanpa debugger lagi.

bambuntu
sumber

Jawaban:

27

Jika Anda menggunakan Upstart 1.4 atau yang lebih baru, masukkan console logke dalam pekerjaan Upstart Anda dan semua output ke stdout / stderr akan berakhir /var/log/upstart/<job>.log. Kemudian Anda dapat melakukan tail -f /var/log/upstart/<job>.log &agar output muncul di terminal.

Tuminoid
sumber
Agak terlambat ke pesta, tetapi jawaban ini menyelamatkan saya :) Juga sepertinya ini bekerja untuk saya tanpa pengaturan khusus dalam file conf pemula. Bagi saya ini harus menjadi jawaban yang diterima.
rslite
Tidak tahu kaya baru berhasil log layanan berada di /var/log/upstart. Sangat berguna, terima kasih.
Francisco
2

Ada seluruh bagian tentang teknik debugging di Cookbook Upstart . Hal termudah yang dapat Anda lakukan adalah menambahkan --debugargumen kernel Anda, yang akan meningkatkan verbositas pemula dan membuang semuanya ke syslog. Ya, debugging itu kompleks, ini merupakan cerminan dari kompleksitas bersih yang diperlukan untuk membuat sistem init yang diparalelkan. Saya yakin ada ruang untuk perbaikan.

ppetraki
sumber
2
buku masak tidak menjelaskan lingkungan debugging dengan benar ke pendatang baru. Saya telah melihat penjelasan serupa sebelumnya. Ada yang kurang atau membuat asumsi guru. Ini sangat menyebalkan bagi orang-orang yang ingin menambah komunitas dan baru memulai. Saya tidak pernah berlari ke lingkungan pemrograman yang tidak menyediakan baris kode di mana kesalahan terjadi kecuali dalam perakitan, di mana Anda menciptakan kembali roda, sehingga dapat dimaafkan.
bambuntu
Nah, apa yang akan Anda sarankan? Ini dokumen terbuka. Jika Anda memiliki teknik debugging yang melompat di atas apa yang disajikan di sana, silakan tambahkan. Masalah OP lebih merupakan hasil dari tidak memahami bagaimana mengelola paradigma unix dasar di dalam runtime pilihan tambahan vs konteks yang digunakan. Hanya karena Anda menggunakan python atau [masukkan bahasa runtime yang mewah di sini] tidak berarti Anda bisa mengabaikan runtime mendasar, UNIX.
ppetraki
2

Ketika saya menulis daemon python saya menangkap semua pengecualian dan kemudian melemparkan ke file log. Saya tidak hanya menggunakan untuk debug, tetapi juga dalam produksi. Saya memiliki skrip kecil yang saya jalankan setiap pagi yang mencari sesuatu yang mengganggu dalam log.

Ini juga membantu menjaga daemon tetap berjalan, tentu saja.

Beberapa kode contoh (saya menghapus bagian yang tidak menarik):

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)

Di mana actua () adalah daemon yang sebenarnya (ia juga menulis untuk mencatat). Perhatikan bahwa saya juga memiliki variabel DEBUG dalam file pengaturan, ketika itu Benar, saya tidak garpu daemon sehingga dijalankan pada konsol.

Daemon

Daemon adalah unix yang setara dengan layanan windows. Mereka adalah proses yang berjalan di latar belakang independen dari proses lain. Itu berarti bahwa ayah mereka biasanya init, dan bahwa mereka terlepas dari segala tty. Karena mereka independen, tidak ada tempat yang telah ditentukan untuk memberikan hasil mereka.

Ada banyak pustaka python dan cuplikan untuk membuat daemon, dalam contoh di atas saya menggunakan fungsi saya sendiri, yang menggabungkan beberapa ide dari versi Steinar Knutsens dan Jeff Kunces. Sesederhana mungkin, perhatikan bahwa saya bercabang dua kali .

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()
Javier Rivera
sumber
Baiklah. karena Anda sudah masuk ke syslog, maka cukup filter keluar pesan daemon Anda dan buang ke konsol. Saya tidak melihat mengapa ini khusus untuk pemula? SysV init akan memiliki masalah yang sama.
ppetraki
Anda benar, itu tidak khusus untuk pemula, untuk mengatakan yang sebenarnya sebagian besar server saya menjalankan 8.04, tidak ada pemula. Tapi ini juga berlaku untuk pemula. OP menanyakan cara men-debug skrip python dengan pemula, bukan untuk metode yang hanya bekerja dengan pemula. Saya tidak masuk ke syslog tetapi ke file tertentu, dan 'trik' di sini adalah menangkap semua pengecualian dan membuang jejak stack ke file itu.
Javier Rivera
baik, itu hanya mengelola stdout berdasarkan konteksnya kan? Saya tahu banyak daemon unix yang memiliki verbositas logging yang setara terlepas dari apakah itu melekat pada tty atau berfungsi sebagai daemon. Jika ini adalah Ruby, saya akan menumpang atau menghias metode kelas dasar yang digunakan pengecualian untuk menghasilkan. Saya yakin hal serupa dapat dilakukan dengan Python. Anda mungkin lebih baik mengajukan pertanyaan ini di stack exchange yang tepat. Ini lebih merupakan masalah dasar unix daemon coding / desain, dan seperti yang Anda nyatakan, itu tidak ada hubungannya dengan skrip init.
ppetraki
Saya masih terbiasa dengan istilah itu. Saya berasumsi oleh daemon, maksud Anda skrip tertentu yang berjalan di latar belakang. Dalam kode Anda, saya hanya meletakkan skrip saya di tempat actua () untuk mendapatkan panggilan balik untuk panggilan skrip itu? Apakah ada cara untuk menyalurkannya ke konsol alih-alih file?
bambuntu
1
daemon dalam arti yang berdiri sendiri biasanya terlepas dari tty mereka mulai, telah menutup menangani file asli mereka ke stdin, stdout, dan stdin, dan merupakan anak init. Jadi, jika Anda ingin mencetak pengecualian ke tempat tertentu, cari tahu bagaimana hasilnya, dan arahkan dari sana. linfo.org/daemon.html . Sekali lagi, ini tidak ada hubungannya dengan pemula, atau bahkan init dalam hal ini. Dapatkan program Anda berfungsi dengan benar dalam mode daemon sejati dan kemudian pindahkan ke atas.
ppetraki