sodcalculator

10 Tech How-To

Run a Python Server Monitor as a Linux Service

Guide 10-16435 · Updated · Step by step

This guide shows you how to run a Python server monitor as a background service on Linux using systemd. You’ll end up with a script that starts automatically at boot, restarts if it crashes, and logs its output—all without keeping a terminal open. You’ll need a Linux machine with systemd (most modern distros), a Python script that monitors your server, and sudo access.

What You’ll Need

  • A Linux server or desktop with systemd (check with ps -p 1 -o comm= – should print systemd)
  • Python 3 installed (python3 --version)
  • A Python monitor script (we’ll create one as an example)
  • Sudo or root access to create systemd unit files

Step-by-Step

  1. Create your Python monitor script. Write a script that checks your server (e.g., pings an endpoint, checks disk space, watches a log file). For this guide, we’ll use a simple script that checks if a website is reachable and logs the result. Save it as /opt/server-monitor/monitor.py:
    #!/usr/bin/env python3
    import time
    import urllib.request
    from datetime import datetime
    
    URL = "http://localhost:8080/health"  # change to your server's health endpoint
    LOG_FILE = "/var/log/server-monitor.log"
    
    while True:
        try:
            urllib.request.urlopen(URL, timeout=5)
            status = "UP"
        except Exception:
            status = "DOWN"
        with open(LOG_FILE, "a") as f:
            f.write(f"{datetime.now().isoformat()} {status}\n")
        time.sleep(60)  # check every 60 seconds
    

    Make it executable: sudo chmod +x /opt/server-monitor/monitor.py

  2. Create a systemd service unit file. Create /etc/systemd/system/server-monitor.service with the following content:
    [Unit]
    Description=Python Server Monitor
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/python3 /opt/server-monitor/monitor.py
    Restart=always
    RestartSec=10
    User=root  # or a dedicated user with appropriate permissions
    Group=root
    
    [Install]
    WantedBy=multi-user.target
    

    Adjust ExecStart to point to your Python interpreter and script path. Use which python3 to find the exact path.

  3. Reload systemd and enable the service. Run:
    sudo systemctl daemon-reload
    sudo systemctl enable server-monitor.service
    sudo systemctl start server-monitor.service
    

    The enable command makes it start at boot; start launches it immediately.

  4. Verify it’s running. Check status and logs:
    sudo systemctl status server-monitor.service
    sudo journalctl -u server-monitor.service -f
    

    You should see the service as active (running) and log lines appearing.

  5. Test that it restarts on failure. Kill the process and watch it come back:
    sudo pkill -f monitor.py
    sudo systemctl status server-monitor.service
    

    After a few seconds, it should show as active again thanks to Restart=always.

  6. Optional: Set up log rotation. To prevent the log file from growing forever, create /etc/logrotate.d/server-monitor:
    /var/log/server-monitor.log {
        daily
        rotate 7
        compress
        missingok
        notifempty
    }

    Then run sudo logrotate -f /etc/logrotate.d/server-monitor to test.

Common Mistakes

  • Wrong Python path in ExecStart. Using python instead of python3, or a path that doesn’t exist, causes the service to fail immediately. Always use the full path from which python3.
  • Forgetting to make the script executable. Even though systemd runs it with Python, a non-executable script can cause permission errors. Use chmod +x.
  • Not reloading systemd after editing the unit file. If you change the .service file, you must run sudo systemctl daemon-reload before restarting the service, or your changes won’t take effect.
  • Using a relative path for the script. Always use absolute paths in ExecStart.
  • Running as root when not necessary. If your script only needs to read logs or make HTTP requests, create a dedicated user with minimal permissions to reduce security risks.

Tips

  • Use EnvironmentFile= in the service unit to store configuration like URLs or thresholds separately from the script.
  • Add StandardOutput=append:/var/log/server-monitor.out and StandardError=append:/var/log/server-monitor.err to capture stdout and stderr separately if you need them.
  • If your script uses a virtual environment, set ExecStart=/path/to/venv/bin/python /opt/server-monitor/monitor.py.
  • For more complex monitoring, consider using Type=notify with sd_notify, but that requires extra code in your script.
  • Test the service after a reboot: sudo reboot and then check systemctl status.

Troubleshooting

  • Service fails to start. Check sudo systemctl status server-monitor.service for error messages. Common issues: missing Python, syntax errors in your script, or permission problems. Run sudo journalctl -u server-monitor.service -n 50 for detailed logs.
  • Service starts but exits immediately. If your script runs once and exits (e.g., no loop), systemd will restart it repeatedly. Make sure your script has an infinite loop or use Type=oneshot if it’s meant to run once.
  • Logs not being written. Check file permissions: the user running the service must have write access to the log file. Create the file with sudo touch /var/log/server-monitor.log and sudo chown root:root /var/log/server-monitor.log (or the user you’re using).
  • Service restarts too often. Increase RestartSec to a higher value (e.g., 30) to avoid rapid restart loops.
  • Can’t enable service. If systemctl enable fails, ensure the unit file has an [Install] section and that you ran daemon-reload.

Frequently Asked Questions

How do I stop the service permanently?

Run sudo systemctl disable --now server-monitor.service. This stops it and removes the boot-time link.

Can I run multiple monitors as separate services?

Yes, create separate unit files (e.g., server-monitor-api.service) with different ExecStart paths. Each runs independently.

How do I update the Python script without restarting the service?

Edit the script, then restart the service with sudo systemctl restart server-monitor.service. If you want hot-reload, you’d need to implement it in the script (e.g., watch a config file).

What if my server doesn’t use systemd?

Older distros use SysV init or Upstart. For SysV, create an init script in /etc/init.d/. For Upstart, use a .conf file in /etc/init/. The concepts are similar but the syntax differs.

How do I see the logs in real time?

Use sudo journalctl -u server-monitor.service -f. This follows new log entries as they appear.

Can I run the monitor as a non-root user?

Yes, change User= and Group= in the service file to your desired user. Ensure that user has read access to the script and write access to the log file.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →