If, like many sysadmins, you are an aficionado of cron scripts launched with * * * * * /I/launch/my/script.sh, this article should make you think of another way to do it using all the power and ease offered by systemd.
We will write a python script that will provide a continuous loop to execute the actions you define.
We will see how to run this script as a systemd service, view the logs in journalctl, and see what happens if the script crashes.
Let's consider the following script my_service.py:
"""
Sample script to run as script
"""
import time
import logging
import sys
from systemd.journal import JournaldLogHandler
# Get an instance of the logger
LOGGER = logging.getLogger(__name__)
# Instantiate the JournaldLogHandler to hook into systemd
JOURNALD_HANDLER = JournaldLogHandler()
JOURNALD_HANDLER.setFormatter(logging.Formatter(
'[%(levelname)s] %(message)s'
))
# Add the journald handler to the current logger
LOGGER.addHandler(JOURNALD_HANDLER)
LOGGER.setLevel(logging.INFO)
class Service(): # pylint: disable=too-few-public-methods
"""
Launch an infinite loop
"""
def __init__(self):
duration = 0
while True:
time.sleep(60)
duration += 60
LOGGER.info("Total duration: %s", str(duration))
# will failed after 4 minutes
if duration > 240:
sys.exit(1)
if __name__ == '__main__':
LOGGER.info("Starting the service")
Service()
We start by instantiating the necessary variables to send logs in journald. The script then launches an infinite loop and pauses for 60 seconds (which is the minimum of a cron execution, so we can go below this limitation).
Note
I personally use this script in a more advanced form, which continuously queries a database and executes jobs based on the information retrieved via the rundeck API