This short project of writing and managing a daemon will provide many benefits for me going forward in any setting. Although this particular daemon will showcase the ability of a program that runs automatically in the background, I will use it in a future project developing a dynamic firewall using Suricata.
So let’s look at an example daemon I made named python_daemon1.py:
As you can see, I started with importing modules necessary for proper times and dates when logging. Debug is a variable that we have declared if we want to come back for debugging. I put a count variable outside of the while loop equal to 1. Inside the while loop which runs forever, I use a try/except block. So it will ‘try’ the code underneath the block and if it works with no errors, it will skip the except block. If it fails, it will immediately move to the first line of the except block.
The first line is a variable called the_time which gives us the standard utc time. The next string variable log_entry, will enter the time and count from the variables on the end of the string. Next, we make a new variable called ‘f‘ that opens my python_daemon1.log file in the /var/log directory. I use the ‘a‘ function to open it and add to it. Next is f.write to write the log entry string into it. It will then close that file. The following is the debug which if set to true, will print out my different stuff along the way. I next increment my count by one and end it with a time.sleep argument of 5 which means it takes 5 seconds to do nothing before it cycles over it again.
Inside the ‘except‘ block, it is very similar to the ‘try‘ block but it will write an error to the python_daemon1_error.log in a new variable called ‘g‘. In that error log will be the time of error and new line breaks before the traceback comment. The most important in the ‘except‘ block is the traceback.format_exc which can pull the full traceback error for understanding. This helps with very long scripts and gives real-time comments. It then closes and is followed by the time.sleep argument which sits for 60 seconds before trying again.
The rest of this post is how to manage and configure a daemon manager so I don’t have to manually do it every time I get onto my virtual environment. With that said, I started by installing supervisor which is a daemon manager that does it all.
Next, I needed to tell supervisor to run my program so I headed to the /etc/supervisor directory to find all configuration files. I then created a daemon for the conf.d directory which is pictured below. The program name will be daemon as you see.
As you see by the command, I needed to move my python_daemon1.py to the /opt directory which is a good place for add-on software application packages.
From here, the next steps include restarting and rereading the supervisor service to put my daemon in there. As you see below, it is up and running!
Lastly, after some research on best practices, it was advised to restart them daily. With that said, I used another daemon manager called Cron which will run commands in intervals for you. So I ran a cron command and opened it using option 2 so I could add a line using VIM.
I added the single line on the bottom that will restart all my daemons once a day to ensure everything is working properly.
The final piece is now checking if my daemon is working. Let’s check out the log file!
As you can see, all the information we asked for in our original script is outputted with the date, time, and five second intervals before going through it again. Some takeaways from this project included skills in:
- Python Daemon Creation
- Cron
- Supervisor
- Error Handling
Thanks for following along.