5
[root@localhost etc]# systemctl status blu_av
● blu_av.service - avscan
   Loaded: loaded (/etc/systemd/system/blu_av.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2018-03-16 16:31:14 IST; 3s ago
 Main PID: 31934 (av)
   CGroup: /system.slice/blu_av.service
           ├─31934 /opt/services/av
           └─31956 /opt/services/av

Mar 16 16:31:14 localhost.localdomain systemd[1]: Started avscan.
Mar 16 16:31:14 localhost.localdomain systemd[1]: Starting avscan...

If the above is the output of my status. I want to retrieve the service name, uptime and status by using a python script.

Chris Maes
  • 35,025
  • 12
  • 111
  • 136
user9279273
  • 75
  • 1
  • 1
  • 12

4 Answers4

15

systemd services have a whole list of properties. To get the start time for example; you could run:

systemctl show your.service --property=ActiveEnterTimestamp

which would give something like:

ActiveEnterTimestamp=Fri 2019-05-03 09:35:02 CEST

To see the list of all properties; just run

systemctl show your.service
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
5

systemctl status has an option --output that allows to use the options of journalctl.

Try JSON which could easily be parsed by Python:

$ sudo systemctl status --output=json-pretty nginx
  • 1
    The `--output` flag unfortunately only affects the formatting of the journal output displayed after the service status information. – asherkin Mar 30 '22 at 16:06
3

Maybe you can try regular expression to parse the output. Here is what I used. Please have a look and comment.

import subprocess, re

def read_status(service):
    p =  subprocess.Popen(["systemctl", "status",  service], stdout=subprocess.PIPE)
    (output, err) = p.communicate()
    output = output.decode('utf-8')

    service_regx = r"Loaded:.*\/(.*service);"
    status_regx= r"Active:(.*) since (.*);(.*)"
    service_status = {}
    for line in output.splitlines():
        service_search = re.search(service_regx, line)
        status_search = re.search(status_regx, line)

        if service_search:
            service_status['service'] = service_search.group(1)
            #print("service:", service)

        elif status_search:
            service_status['status'] = status_search.group(1).strip()
            #print("status:", status.strip())
            service_status['since'] = status_search.group(2).strip()
            #print("since:", since.strip())
            service_status['uptime'] = status_search.group(3).strip()
            #print("uptime:", uptime.strip())

    return service_status

def main():
    service = 'mysql'
    reponse = read_status(service)

    for key in reponse:
        print('{}:{}'.format(key, reponse[key]))


if __name__ == '__main__':
    main()

Output:

service:mysql.service
status:active (running)
since:Fri 2018-03-16 09:17:57 CET
uptime:6h ago

I simply use this to check my regular expressions.

Sumit Jha
  • 1,601
  • 11
  • 18
0

You could get the output from systemctl by using subprocess.check_output() and parse it afterwards.

sewi
  • 71
  • 1
  • The interesting step would be the parsing. How would you do this? –  Mar 16 '18 at 13:49
  • @LutzHorn @user9279273 Just split the output with `\n` as separator and you'll get an array containing every single line of output. Getting the desired information should be easy from there on. – sewi Mar 16 '18 at 14:08