FreeBSD and Python - Cara Menulis Daemon Script Part 1

· 2 min read

Sistem pencatatan juga harus dipertimbangkan saat menangani proses yang berjalan di latar belakang Daemon terlepas dari TTY. Ini berarti ia tidak dapa

Beberapa catatan tambahan. Meskipun kata “daemon” mungkin terdengar seperti sesuatu yang jahat, kata itu tidak ada hubungannya dengan Setan, sebenarnya kata itu berasal dari kata Yunani da?µ??, yang merujuk pada roh yang dimiliki manusia dan yang pada akhirnya mendefinisikan mereka.

Daemon adalah sebuah proses. Tidak lebih dan tidak kurang dari proses peramban Anda. Perbedaan utamanya adalah bahwa daemon adalah proses yang tidak memerlukan masukan pengguna untuk berfungsi. Bayangkan, misalnya, tentang server web yang tidak menunggu penggunanya sendiri untuk melakukan suatu tindakan, tetapi menunggu host lain di jaringan untuk melakukan permintaan. Permintaan tersebut perlu diproses tanpa ada manusia yang ikut serta di dalamnya.

Utilitas daemon terlepas dari terminal pengendali dan mengeksekusi program yang ditentukan oleh argumennya. Hak istimewa dapat diberikan kepada pengguna tertentu. Output dari proses daemonisasi dapat diarahkan ke syslog dan ke berkas log. Kita dapat membuat proses daemon dalam Python melalui argumen “daemon” ke konstruktor multiprosesing atau melalui properti “daemon”.

Setiap program Python dieksekusi dalam sebuah Proses, yang merupakan contoh baru dari interpreter Python. Proses ini memiliki nama MainProcess dan memiliki satu utas yang digunakan untuk mengeksekusi instruksi program yang disebut MainThread. Baik proses maupun utas dibuat dan dikelola oleh sistem operasi yang mendasarinya. Terkadang kita mungkin perlu membuat proses anak baru dalam program kita untuk mengeksekusi kode secara bersamaan. Python menyediakan kemampuan untuk membuat dan mengelola proses baru melalui kelas multiprocessing.Process.

Daemon diucapkan “dee-mon”, seperti ejaan alternatif “demon”. Idenya adalah bahwa proses latar belakang seperti “daemon” atau roh (dari bahasa Yunani kuno) yang melakukan tugas untuk Anda di latar belakang. Anda juga dapat menyebut proses daemon sebagai daemonic.

Suatu proses dapat dikonfigurasikan menjadi daemon atau bukan, dan sebagian besar proses dalam pemrograman bersamaan, termasuk proses induk utama, adalah proses non-daemon (bukan proses latar belakang) secara default. Properti menjadi proses daemon atau bukan mungkin tidak didukung oleh sistem operasi dasar yang benar-benar membuat dan mengelola eksekusi thread dan proses.


1. Apa Itu Daemon Python

Pada tahun 2009 PEP 3143 dibuat, tujuannya adalah untuk membuat "paket dalam pustaka standar Python yang menyediakan antarmuka sederhana untuk tugas sebagai proses daemon. Meskipun tujuan ini bukan tidak mungkin dan cukup banyak orang yang tertarik untuk melihat proyek tersebut berhasil, namun hal itu tidak berhasil. Orang yang bertanggung jawab untuk melakukannya tidak memiliki cukup waktu tersisa dan tidak ada yang turun tangan untuk menyelamatkan proyek tersebut. Kematian yang menyedihkan bagi sebuah proyek yang bagus.

Tragedi ini tidak terlalu memengaruhi fungsionalitas python-daemon (pada dasarnya ia mencakup semua yang dibutuhkan untuk sebuah daemon), tetapi lebih pada dokumentasinya. Seperti yang saya katakan sebelumnya, titik terlemah adalah dokumentasi dalam PEP dan sebagian ada dalam kode itu sendiri.

Sejak daemon python pertama kali muncul, pustaka python memperkenalkan daemon runner untuk menangani daemon. Namun, saat ini pustaka Daemon Runner tidak lagi digunakan, dan sebagai gantinya pustaka API DaemonContext yang digunakan dalam DaemonRunner digunakan. Memang benar bahwa DaemonRunner memperluas fungsionalitas DaemonContext, tetapi melakukannya dengan cara yang sangat kuno (misalnya tidak menggunakan argparse). Ini mungkin menjadi alasan mengapa akhirnya tidak digunakan lagi. Tanpa basa-basi lagi, DaemonContext memudahkan untuk memulai pekerjaan daemon hanya dengan manajer konteks.


2. Bagaimana Cara Membuat Daemon Python

Langkah pertama untuk menggunakan Python Daemon adalah menginstal aplikasi Python Daemon terlebih dahulu. Perintah berikut digunakan untuk menginstal python daemon.

root@ns1:~ # pip install python-daemon

Untuk membuat daemon python dan agar lebih mudah dipelajari, berikut ini akan diberikan contoh file daemon. Kita buat file dengan nama /tmp/gunungsemeru.py dan masukkan skrip berikut ke dalam file /tmp/gunungsemeru.py.

root@ns1:/ # ee /tmp/gunungsemeru.py
#!/usr/local/bin/python

# Imports #
import time

# Globals #
TTL_SECONDS = 30
TTL_CHECK_INTERVAL = 5

# Fuctions #

# Main #
print("Started!")
for i in range(1, TTL_SECONDS + 1):
time.sleep(1)
if i % TTL_CHECK_INTERVAL == 0:
print("Running for " + str(i) + " seconds...")
print("TTL reached, terminating!")
exit(0)


Kemudian buat izin file pada file /tmp/gunungsemeru.py.

root@ns1:/tmp # chmod +x /tmp/gunungsemeru.py

Sekarang kita uji file /tmp/gunungsemeru.py, apakah daemon Python berjalan atau tidak.

root@ns1:~ # cd /tmp
root@ns1:/tmp #
./gunungsemeru.py restart
Started!
Running for 5 seconds...

Bagian utama program pertama-tama mengeluarkan pesan awal di terminal, lalu memasukkan for loop, yang menghitung dari 1 hingga 30. Dalam Python, kita dapat melakukannya dengan memberikan daftar nilai setelah kata kunci in. Menghitung hingga 5 dapat ditulis sebagai i dalam [1, 2, 3, 4, 5].

Hal berikutnya yang perlu dieksplorasi adalah penanganan sinyal. Karena daemon pada dasarnya adalah program yang berjalan di latar belakang, kita memerlukan cara untuk memberi tahunya agar berhenti, misalnya. Ini biasanya dilakukan dengan menggunakan sinyal. Kita dapat mengirim beberapa sinyal ke program normal yang berjalan di terminal dengan menekan kombinasi tombol, sementara semuanya dapat dikirim dengan perintah kill.

Jika kita menekan CTRL + C misalnya, kita mengirim SIGINT ke aplikasi yang sedang berjalan, yang memberitahunya untuk "menghentikan operasi". Sesuatu yang agak mirip adalah SIGTERM, yang berarti "hei, tolong berhenti". Ini adalah sinyal penghentian yang baik, yang memungkinkan program untuk melakukan pembersihan dan kemudian mematikannya dengan benar.

Namun, jika kita menggunakan kill-9, kita akan mengirim SIGKILL, sinyal kill yang tidak dapat dilewati, yang secara efektif berarti "mati!" untuk proses yang ditargetkan (jika kita pernah melakukannya pada database langsung atau aplikasi sensitif lainnya, kita tahu bahwa kita benar-benar harus berpikir sebelum menggunakannya atau kita mungkin akan mengalami berbagai kesulitan selama beberapa jam ke depan).

Berikut ini adalah skrip untuk memberikan sinyal ke daemon Python. Pertama-tama hapus isi file /tmp/gunungsemeru.py dan ganti dengan skrip di bawah ini.

root@ns1:/ # ee /tmp/gunungsemeru.py
#!/usr/local/bin/python

# Imports #
import signal
import time

# Globals #
TTL_SECONDS = 30
TTL_CHECK_INTERVAL = 5

# Fuctions #
def signal_handler(signum, frame):
print("Received signal" + str(signum) + "!")
if signum == 2:
exit(0)

# Main #
signal.signal(signal.SIGHUP, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGQUIT, signal_handler)
signal.signal(signal.SIGILL, signal_handler)
signal.signal(signal.SIGTRAP, signal_handler)
signal.signal(signal.SIGABRT, signal_handler)
signal.signal(signal.SIGEMT, signal_handler)
#signal.signal(signal.SIGKILL, signal_handler)
signal.signal(signal.SIGSEGV, signal_handler)
signal.signal(signal.SIGSYS, signal_handler)
signal.signal(signal.SIGPIPE, signal_handler)
signal.signal(signal.SIGALRM, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
#signal.signal(signal.SIGSTOP, signal_handler)
signal.signal(signal.SIGTSTP, signal_handler)
signal.signal(signal.SIGCONT, signal_handler)
signal.signal(signal.SIGCHLD, signal_handler)
signal.signal(signal.SIGTTIN, signal_handler)
signal.signal(signal.SIGTTOU, signal_handler)
signal.signal(signal.SIGIO, signal_handler)
signal.signal(signal.SIGXCPU, signal_handler)
signal.signal(signal.SIGXFSZ, signal_handler)
signal.signal(signal.SIGVTALRM, signal_handler)
signal.signal(signal.SIGPROF, signal_handler)
signal.signal(signal.SIGWINCH, signal_handler)
signal.signal(signal.SIGINFO, signal_handler)
signal.signal(signal.SIGUSR1, signal_handler)
signal.signal(signal.SIGUSR2, signal_handler)
#signal.signal(signal.SIGTHR, signal_handler)

print("Started!")
for i in range(1, TTL_SECONDS + 1):
time.sleep(1)
if i % TTL_CHECK_INTERVAL == 0:
print("Running for " + str(i) + " seconds...")
print("TTL reached, terminating!")
exit(0)

Contoh skrip di atas telah menambahkan fungsi yang disebut "signal_handler", karena memang itulah fungsinya. Jika program ini dijalankan, ia akan menangani setiap sinyal yang dapat dikirim pada sistem FreeBSD (jalankan kill -l untuk mencantumkan semua sinyal yang tersedia pada sistem operasi mirip Unix).

Sistem pencatatan juga harus dipertimbangkan saat menangani proses yang berjalan di latar belakang Daemon terlepas dari TTY. Ini berarti ia tidak dapat lagi menerima input seperti biasa dari STDIN. Namun, kami menyelidiki sinyal tersebut sehingga tidak menjadi masalah. Namun, ini juga berarti daemon tidak dapat menggunakan STDOUT atau STDERR untuk mencetak apa pun ke terminal.

Ke mana data yang ditulis oleh daemon, misalnya STDOUT, pergi? Ini masuk ke log sistem. Jika tidak ada konfigurasi khusus untuknya, Anda dapat menemukannya di /var/log/messages. Karena kami mengharapkan cukup banyak keluaran debug selama fase pengembangan, kami tidak ingin mengacaukan /var/log/messages dengan semua itu. Jadi untuk menulis daemon kecil yang berperilaku baik, ada satu topik lagi yang harus kita perhatikan yaitu "Logging". Berikut ini adalah skrip logging untuk daemon Puthon.

root@ns1:/ # ee /tmp/gunungsemeru.py
#!/usr/local/bin/python

# Imports #
import logging
import signal
import time

# Globals #
TTL_SECONDS = 30
TTL_CHECK_INTERVAL = 5

# Fuctions #
def handler_sigterm(signum, frame):
logging.debug("Exiting on SIGTERM")
exit(0)

def handler_sigint(signum, frame):
logging.debug("Not going to quit, there you have it!")

# Main #
signal.signal(signal.SIGINT, handler_sigint)
signal.signal(signal.SIGTERM, handler_sigterm)
try:
logging.basicConfig(filename='bdaemon.log', format='%(levelname)s:%(message)s', level=logging.DEBUG)
except:
print("Error: Could not create log file! Exiting...")
exit(1)

logging.info("Started!")
for i in range(1, TTL_SECONDS + 1):
time.sleep(1)
if i % TTL_CHECK_INTERVAL == 0:
logging.info("Running for " + str(i) + " seconds...")
logging.info("TTL reached, terminating!")
exit(0)

Satu-satunya hal yang perlu dilakukan adalah mengubah pernyataan cetak sehingga kita menggunakan pencatatan. Bergantung pada seberapa penting entri log tersebut, kita juga dapat menggunakan berbagai tingkatan dari yang paling tidak penting (DEBUG) hingga yang paling penting (KRITIS). Kita dapat menunggu hingga program selesai dan kemudian melihat log, atau dapat membuka terminal kedua dan mengetik -f bdaemon.log di sana untuk melihat output saat program sedang berjalan.

Oke! dengan artikel di tahap 1, kita memiliki semua yang diperlukan untuk melakukan daemonisasi program python.
Subscribe on LinkedIn FreeBSD and Python - Cara Menulis Daemon Script Part 1

Enclosures Link: FreeBSD and Python - Cara Menulis Daemon Script Part 1

Silahkan Berkomentar, Kakak...! Bunda...!

Posting Komentar