3

TLDR

How do I get a view of the status of all services on a target ?

something like :

# obviously, 'systemctl status' does not have this output :
$ systemctl --user status service.target
service.target: inactive (dead)
├── backend.service:  active
├── db.service: active
├── frontend.service: active
└── scheduler.service: inactive (dead)

Context

We have several systemd units, which are parts of a more global service, so we have written a service.target with all these units as dependencies.

For a more complete context :

  1. the units and target are actually user units and target units
  2. the service.targetfile consists only of a description :

    #cat .config/systemd/user/service.target
    [Unit]
    Description = Service global target
    
  3. service.target's dependencies are listed in the filesystem :

    $ tree .config/systemd/user
    ├── backend.service
    ├── db.service
    ├── frontend.service
    ├── scheduler.service
    ├── service.target
    └── service.target.requires
       ├── backend.service -> ../backend.service
       ├── db.service -> ../db.service
       ├── frontend.service -> ../frontend.service
       └── scheduler.service -> ../scheduler.service
    

With this setup, systemctl --user start service.target and systemctm --user stop service.target works like we expect.

What I would like

I would like to have a command or a script, which would tell me wether the dependencies of the target are all up, only partially up, or all down.

From what I tried :

  • systemctl --user status service.target will correctly tell me (and exit with 0) if all services are up, but will not help me to distinguish between "some are up, some are down" and "all are down" (in both case : exit code is 3, status message says inactive (dead))

  • systemctl --user list-dependencies service.target does not give an output stable enough to parse

  • systemctl --user status will give me a detailed overview of all processes started by systemd user services, but I d'ont know how to narrow this list down to "only the services under service.target"

Question

What is the most stable way to get the status of all the services on which a systemd target depends ?

Should we modify our setup ?

LeGEC
  • 183
  • 7

2 Answers2

4

This topic was recently discussed in How to create a virtual systemd service to stop/start several instances together?.

The summary of options is:

  1. systemctl status $(systemctl list-dependencies --plain your.target)
  2. Comment on the systemd feature request to add this as a built-in feature
Mark Stosberg
  • 3,901
  • 24
  • 28
1

While poking around systemd, I found the following command gives me a more direct list of the services I want to inspect :

systemctl --user show --property=ConsistsOf your.target

It has the added benefit of returning "" on base services :

$ systemctl --user show --property=ConsistsOf service.target
ConsistsOf=backend.service db.service frontend.service scheduler.service
$ systemctl --user show --property=ConsistsOf backend.service
ConsistsOf=

@MarkStosberg commented (correctly) that :

  1. It's not alphabetical
  2. The ConsistsOf= at the beginning requires some form of stripping anyway before passing it to another command

The benefits I see are :

  1. It only lists items which are declared as PartOf of my target :
    for example when I use list-dependencies on db.service, I see :

    $ systemctl --user list-dependencies --plain db.service
    db.service
      -.slice
      basic.target
      paths.target
      sockets.target
      dirmngr.socket
      gpg-agent-browser.socket
      gpg-agent-extra.socket
      gpg-agent-ssh.socket
      gpg-agent.socket
      timers.target
    

    (which is technically true, but irrelevant for my use case) while :

    $ systemctl --user show --property=ConsistsOf db.service
    ConsistsOf=
    

    does show an empty list

  2. I didn't state it in my original question, but we actually use some extra parameters (backend.service can actually be backend@p0.service or backend@p1.service or ...) When using list-dependencies on our target, somehow, backend@p0.service gets listed twice :

    $ systemctl --user list-dependencies --plain service.target
    service.target
      backend@p0.service
      backend@p0.service
      db.service
      frontend.service
      scheduler.service
    
  3. the unit itself is listed in list-dependencies, but not in ConsistsOf

So I had to apply some processing on the output anyway.

Just sharing my experience ; thanks for your answer and indications which pointed me in the right direction.

LeGEC
  • 183
  • 7
  • For targets, this is not more-direct than `systemctl list-dependencies --plain`, it it is exactly the same list of dependencies, 1. It's not alphabetical. 2. It includes "ConsistsOf=" at the beginning, so the output can't be directly passed to another command without first stripping this out. This variation could be useful when there is a difference between the "dependencies" and the "ConsistsOf" values. – Mark Stosberg Jul 26 '18 at 14:13