systemd-logo

How to create custom systemd service – Example of OS monitoring Python service

If you want run your application as a systemd service, using systemctl, you can do that easily by creating service file.

As example, we are going to run Python Flask to show basic info about OS.

Project structure:

project structureLet’s create file monitor_app.py:

from flask import Flask, render_template
import os

app = Flask(__name__)

@app.route('/')
def index():
 return render_template('monitor.html', info = os.uname())

if __name__ == '__main__':
 app.run()

We are using flask, render_template (to render OS data with HTML template) and os to get basic OS info via uname() method.

And here is simple template monitor.html from templates folder:

<!DOCTYPE html>
<html>
<head>
    <title>Monitor result</title>
</head>
<body>
<h1>System information</h1>
{% for row in info %}
<div><p><b>{{ row }}</b></p></div>
<hr>
{% endfor %}
</body>
</html>

 

Now you can try run it: python monitor_app.py and visit http://localhost:5000/ to see page with provided OS information.

You can download code on GitHub.

Create service file

Service files are stored in /usr/lib/systemd/system/ and here we’d like to create our service file SERVICE_NAME.service where SERVICE_NAME will be used as service name.

 

For this example, I’ll call my service mymonitor. I am using vim, but feel free to use text editor of your choice.

vim /usr/lib/systemd/system/mymonitor.service

And this is definition of service:

[Unit]
Description=Example service for monitoring
[Service]
ExecStart=python /opt/mymonitor_example/mymonitor.py
User=root
[Install]
WantedBy=multi-user.target

This service file is really simple one and you should pay attention to documentation, because we can define a really detailed description of service. For more information, visit this service page and this unit page.  I’d like to point out that it is really useful to read it, at least this part about section options where you can find information .

Now we can reload systemctl by running command systemctl daemon-reload.

daemon-reload Reload systemd manager configuration. This will rerun all generators (see systemd.generator(7)), reload all unit files, and recreate the entire dependency tree. While the daemon is being reloaded, all sockets systemd listens on behalf of user configuration will stay accessible. This command should not be confused with the reload command.

Put it together

We defined command python /opt/mymonitor_example/mymonitor.py in service file to execute. So copy (or clone from GitHub) our project with name mymonitor_example, copy this folder to /opt/ and our service definition is correct and we are ready to start using it.

 

Use systemctl commands to work with our service.

# Start service
systemctl start mymonitoring

# Service status
systemctl status mymonitoring

# Stop service
systemctl stop mymonitoring

# Restart service
systemctl restart mymonitoring

 Other tips

To check status of your service, use journalctl command. See docs.

Do you want run your java application? Just use this in service file ExecStart=/usr/bin/java -jar /path/to/my_application.jar in service section.

You can define service dependencies by Requires option in Unit section. There are also others options to define your service dependencies.

Very nice options are conditions and asserts, here is anchor to doc.

Unit files are loaded from a set of paths determined during compilation, described in the two tables below. Unit files found in directories listed earlier override files with the same name in directories lower in the list. See this part of docs.

Aleš Laňar
Senior Engineer Software ve společnosti CA Technologies

Leave a Reply

Your email address will not be published. Required fields are marked *