Gỡ lỗi: Đầu ra giao diện điều khiển và tập lệnh khởi động


16

Làm thế nào để bạn gửi đầu ra của một tập lệnh khởi động đến một thiết bị đầu cuối để tìm tracebacks trong mã python? Nó khiến tôi không bao giờ làm được việc mà không có dấu vết trước đây chỉ mất một giây. Tôi phải thực hiện một số cuộc gọi ghi tập tin để theo dõi lỗi. Những gì đã mất thứ hai để tìm thấy trước với một trac trở lại là trong vài phút. Điều này thật đáng thương. Điều này đã diễn ra trong vài tuần nay và tôi phát ốm vì nó. xin vui lòng một số lên tiếng về điều này xin vui lòng. Tôi cảm thấy như tôi đang sử dụng lắp ráp mà không cần trình gỡ lỗi một lần nữa.

Câu trả lời:


27

Nếu bạn sử dụng Upstart 1.4 hoặc mới hơn, hãy đưa console logvào công việc Upstart của bạn và tất cả đầu ra cho thiết bị xuất chuẩn / stderr sẽ kết thúc /var/log/upstart/<job>.log. Sau đó, bạn có thể làm tail -f /var/log/upstart/<job>.log &để có đầu ra xuất hiện trong thiết bị đầu cuối.


Loại muộn của bữa tiệc, nhưng câu trả lời này đã cứu tôi :) Cũng có vẻ như điều này hoạt động với tôi mà không có bất kỳ cài đặt đặc biệt nào trong tệp conf mới bắt đầu. Về phần tôi đây phải là câu trả lời được chấp nhận.
rslite

Không biết các bản ghi dịch vụ được quản lý mới bắt đầu /var/log/upstart. Thực sự hữu ích, cảm ơn.
Francisco

2

Có cả một phần về kỹ thuật sửa lỗi trong Upstart Cookbook . Điều đơn giản nhất bạn có thể làm là thêm --debugvào các đối số kernel của mình, điều này sẽ làm tăng tính dài dòng của nó và bỏ mọi thứ vào syslog. Đúng, gỡ lỗi rất phức tạp, đó là sự phản ánh độ phức tạp ròng cần có để tạo ra một hệ thống init song song. Tôi chắc chắn có chỗ để cải thiện.


2
cuốn sách nấu ăn không giải thích chính xác môi trường gỡ lỗi cho người mới. Tôi đã thấy những lời giải thích tương tự trước đây. Có hoặc thiếu hoặc đưa ra giả định guru. Thật là bực bội cho những người muốn thêm vào cộng đồng và chỉ mới bắt đầu. Tôi chưa bao giờ chạy vào một môi trường lập trình không cung cấp dòng mã xảy ra lỗi ngoại trừ khi lắp ráp, nơi bạn đang phát minh lại bánh xe, để có thể tha thứ.
bamb Ubuntu

Vâng, sau đó bạn sẽ đề nghị gì? Đó là một tài liệu mở. Nếu bạn đã có một kỹ thuật sửa lỗi, vượt qua những gì được trình bày ở đó thì hãy thêm nó vào. Các vấn đề của OP là kết quả của việc không hiểu cách quản lý các mô hình unix cơ bản bên trong thời gian chạy bổ sung của mình so với bối cảnh đang được triển khai. Chỉ vì bạn đang sử dụng python hoặc [chèn ngôn ngữ thời gian chạy ưa thích ở đây] không có nghĩa là bạn bỏ qua thời gian chạy cơ bản, UNIX.
ppetraki

2

Khi tôi viết một daemon python, tôi bắt tất cả các ngoại lệ và ném vào tệp nhật ký. Tôi không chỉ sử dụng để gỡ lỗi, mà trong sản xuất cũng vậy. Tôi có một kịch bản nhỏ mà tôi chạy mỗi sáng tìm kiếm thứ gì đó gây khó chịu trong nhật ký.

Nó cũng giúp giữ daemon chạy, tất nhiên.

Một số mã mẫu (tôi loại bỏ các phần không thú vị):

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)

Trong đó Actua () là daemon thực (nó cũng ghi vào nhật ký). Lưu ý rằng tôi cũng có biến DEBUG trong tệp cài đặt, khi đó là True, tôi không rẽ nhánh daemon để nó thực thi trên bàn điều khiển.

Daemon

Daemon là unix tương đương với các dịch vụ windows. Chúng là các tiến trình chạy trong nền độc lập với các tiến trình khác. Điều đó có nghĩa là cha của họ thường là init, và họ bị tách ra khỏi bất kỳ tty nào. Vì chúng độc lập, không có nơi nào được xác định trước để đặt đầu ra của chúng.

Có rất nhiều thư viện và đoạn trích python để tạo một daemon, trong ví dụ trên tôi sử dụng chức năng của riêng mình, kết hợp một số ý tưởng từ các phiên bản Steinar Knutsens và Jeff Kunces. Nó đơn giản nhất có thể, lưu ý rằng tôi rẽ nhánh hai lần .

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()

Tốt. vì bạn đã đăng nhập vào syslog, sau đó chỉ cần lọc các tin nhắn daemon của bạn và chuyển chúng vào bảng điều khiển. Tôi không thấy lý do tại sao điều này là cụ thể để bắt đầu? SysV init sẽ có cùng một vấn đề.
ppetraki

Bạn nói đúng, nó không cụ thể để bắt đầu, nói thật là hầu hết các máy chủ của tôi chạy 8.04, không khởi động. Nhưng nó cũng hợp lệ cho sự khởi đầu. OP đã hỏi làm thế nào để gỡ lỗi các kịch bản python với upstart, không phải cho một phương thức chỉ hoạt động với upstart. Tôi không đăng nhập vào syslog mà vào một tệp cụ thể và 'mẹo' ở đây là bắt tất cả các ngoại lệ và bỏ dấu vết ngăn xếp vào tệp đó.
Javier Rivera

tốt, đó chỉ là quản lý thiết bị xuất chuẩn dựa trên bối cảnh phải không? Tôi biết rất nhiều trình nền unix có độ dài ghi nhật ký tương đương bất kể nó được gắn với tty hay hoạt động như một daemon. Nếu đây là Ruby, tôi sẽ lái xe quá mức hoặc trang trí phương thức lớp cơ sở mà ngoại lệ sử dụng để xuất ra. Tôi chắc chắn một cái gì đó tương tự có thể được thực hiện trong Python. Bạn có thể được phục vụ tốt hơn khi hỏi câu hỏi này về trao đổi ngăn xếp thích hợp. Đây là nhiều hơn một vấn đề thiết kế / mã hóa unix daemon cơ bản, và như bạn đã nói, nó không có gì cụ thể để làm với các script init.
ppetraki

Tôi vẫn đang làm quen với biệt ngữ. Tôi giả sử bởi daemon, bạn có nghĩa là một kịch bản cụ thể chạy trong nền. Trong mã của bạn, tôi chỉ cần đặt tập lệnh của mình thay cho Actua () để nhận các cuộc gọi lại cho lệnh gọi tập lệnh đó? Có cách nào để chuyển nó đến một bàn điều khiển thay vì một tập tin?
bamb Ubuntu

1
daemon theo nghĩa độc lập thường được tách ra khỏi tty mà chúng được bắt đầu, đã đóng các tập tin gốc của chúng để stdin, stdout và stdin và là một đứa trẻ của init. Vì vậy, nếu bạn muốn in các ngoại lệ đến một nơi nào đó cụ thể, hãy tìm hiểu cách chúng được xuất ra và hướng chúng từ đó. linfo.org/daemon.html . Một lần nữa, điều này không có gì để làm với sự khởi đầu, hoặc thậm chí init cho vấn đề đó. Để chương trình của bạn hoạt động chính xác trong chế độ daemon thực và sau đó di chuyển nó lên trên.
ppetraki
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.