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