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


3 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