How to Get systemd Service Status in JSON Format Using systemctl Command


16 views

When working with systemd services in automation scripts or monitoring tools, the standard systemctl status output isn't machine-friendly. While systemd provides JSON output capabilities, applying them to service status requires specific approaches.

The correct way to get JSON-formatted service status is to use systemctl show instead of systemctl status:

systemctl show snapd.service --property=LoadState,ActiveState,SubState,UnitFileState --no-pager --output=json

This will return clean JSON like:

{
  "LoadState": "loaded",
  "ActiveState": "active",
  "SubState": "running",
  "UnitFileState": "enabled"
}

For more comprehensive status including PID and uptime:

systemctl show snapd.service --all --no-pager --output=json

This returns all available properties in JSON format:

{
  "Type": "notify",
  "Restart": "no",
  "MainPID": "738",
  "ActiveEnterTimestampMonotonic": "123456789",
  "ConditionResult": "yes",
  ...
}

For a hybrid approach that includes both structured data and human-readable status:

{
  "status": "$(systemctl status snapd.service --no-pager)",
  "properties": $(systemctl show snapd.service --no-pager --output=json)
}

Here's how to process the JSON in a Python script:

import json
import subprocess

def get_service_json(service_name):
    cmd = [
        "systemctl", "show", service_name,
        "--no-pager", "--output=json"
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    return json.loads(result.stdout)

status = get_service_json("snapd.service")
print(f"Service is {status['ActiveState']} (PID: {status['MainPID']})")

When automating system administration tasks, developers often need to parse service status information programmatically. While systemctl status provides human-readable output, the JSON format is far more useful for scripting and integration with monitoring tools.

Systemd does provide JSON output capabilities through the --output=json flag, but this currently only works for journal entries, not service status metadata. The command:

systemctl status servicename --output=json --plain

Returns a hybrid output where only the journal portion is properly formatted JSON, while the service status remains in text format.

Method 1: Using systemctl show

The most reliable approach is to use systemctl show which outputs properties in key=value format that can be converted to JSON:

systemctl show snapd.service --no-page

To convert this to JSON, you can use a simple Python script:

import json
import subprocess

def get_service_json(service_name):
    output = subprocess.check_output(
        ["systemctl", "show", service_name, "--no-page"]
    ).decode()
    
    result = {}
    for line in output.splitlines():
        if "=" in line:
            key, value = line.split("=", 1)
            result[key] = value
    
    return json.dumps(result, indent=2)

print(get_service_json("snapd"))

Method 2: Combining show and list-units

For more comprehensive information including the relationship between units:

systemctl list-units --all --no-legend --no-pager -o json snapd.service

If you only need certain fields (Loaded, ActiveState, etc.), you can query them directly:

systemctl show snapd.service --property=LoadState,ActiveState,SubState --no-page

Convert to JSON with jq:

systemctl show snapd.service --property=LoadState,ActiveState,SubState --no-page | 
awk -F= '{print "\"" $1 "\": \"" $2 "\""}' | 
jq -n 'reduce inputs as $line (.; . + ($line | fromjson))'

Newer versions include better JSON support. Try:

systemctl show snapd.service --json=pretty