mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2025-06-19 00:17:51 +02:00
289 lines
6.6 KiB
Python
289 lines
6.6 KiB
Python
"""jc - JSON CLI output utility ps Parser
|
|
|
|
Usage:
|
|
|
|
specify --ps as the first argument if the piped input is coming from ps
|
|
|
|
ps options supported:
|
|
- ef
|
|
- axu
|
|
|
|
Compatibility:
|
|
|
|
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
|
|
|
Examples:
|
|
|
|
$ ps -ef | jc --ps -p
|
|
[
|
|
{
|
|
"uid": "root",
|
|
"pid": 1,
|
|
"ppid": 0,
|
|
"c": 0,
|
|
"stime": "Nov01",
|
|
"tty": null,
|
|
"time": "00:00:11",
|
|
"cmd": "/usr/lib/systemd/systemd --switched-root --system --deserialize 22"
|
|
},
|
|
{
|
|
"uid": "root",
|
|
"pid": 2,
|
|
"ppid": 0,
|
|
"c": 0,
|
|
"stime": "Nov01",
|
|
"tty": null,
|
|
"time": "00:00:00",
|
|
"cmd": "[kthreadd]"
|
|
},
|
|
{
|
|
"uid": "root",
|
|
"pid": 4,
|
|
"ppid": 2,
|
|
"c": 0,
|
|
"stime": "Nov01",
|
|
"tty": null,
|
|
"time": "00:00:00",
|
|
"cmd": "[kworker/0:0H]"
|
|
},
|
|
...
|
|
]
|
|
|
|
$ ps -ef | jc --ps -p -r
|
|
[
|
|
{
|
|
"uid": "root",
|
|
"pid": "1",
|
|
"ppid": "0",
|
|
"c": "0",
|
|
"stime": "Nov01",
|
|
"tty": "?",
|
|
"time": "00:00:11",
|
|
"cmd": "/usr/lib/systemd/systemd --switched-root --system --deserialize 22"
|
|
},
|
|
{
|
|
"uid": "root",
|
|
"pid": "2",
|
|
"ppid": "0",
|
|
"c": "0",
|
|
"stime": "Nov01",
|
|
"tty": "?",
|
|
"time": "00:00:00",
|
|
"cmd": "[kthreadd]"
|
|
},
|
|
{
|
|
"uid": "root",
|
|
"pid": "4",
|
|
"ppid": "2",
|
|
"c": "0",
|
|
"stime": "Nov01",
|
|
"tty": "?",
|
|
"time": "00:00:00",
|
|
"cmd": "[kworker/0:0H]"
|
|
},
|
|
...
|
|
]
|
|
|
|
$ ps axu | jc --ps -p
|
|
[
|
|
{
|
|
"user": "root",
|
|
"pid": 1,
|
|
"cpu_percent": 0.0,
|
|
"mem_percent": 0.1,
|
|
"vsz": 128072,
|
|
"rss": 6784,
|
|
"tty": null,
|
|
"stat": "Ss",
|
|
"start": "Nov09",
|
|
"time": "0:08",
|
|
"command": "/usr/lib/systemd/systemd --switched-root --system --deserialize 22"
|
|
},
|
|
{
|
|
"user": "root",
|
|
"pid": 2,
|
|
"cpu_percent": 0.0,
|
|
"mem_percent": 0.0,
|
|
"vsz": 0,
|
|
"rss": 0,
|
|
"tty": null,
|
|
"stat": "S",
|
|
"start": "Nov09",
|
|
"time": "0:00",
|
|
"command": "[kthreadd]"
|
|
},
|
|
{
|
|
"user": "root",
|
|
"pid": 4,
|
|
"cpu_percent": 0.0,
|
|
"mem_percent": 0.0,
|
|
"vsz": 0,
|
|
"rss": 0,
|
|
"tty": null,
|
|
"stat": "S<",
|
|
"start": "Nov09",
|
|
"time": "0:00",
|
|
"command": "[kworker/0:0H]"
|
|
},
|
|
...
|
|
]
|
|
|
|
$ ps axu | jc --ps -p -r
|
|
[
|
|
{
|
|
"user": "root",
|
|
"pid": "1",
|
|
"cpu_percent": "0.0",
|
|
"mem_percent": "0.1",
|
|
"vsz": "128072",
|
|
"rss": "6784",
|
|
"tty": "?",
|
|
"stat": "Ss",
|
|
"start": "Nov09",
|
|
"time": "0:08",
|
|
"command": "/usr/lib/systemd/systemd --switched-root --system --deserialize 22"
|
|
},
|
|
{
|
|
"user": "root",
|
|
"pid": "2",
|
|
"cpu_percent": "0.0",
|
|
"mem_percent": "0.0",
|
|
"vsz": "0",
|
|
"rss": "0",
|
|
"tty": "?",
|
|
"stat": "S",
|
|
"start": "Nov09",
|
|
"time": "0:00",
|
|
"command": "[kthreadd]"
|
|
},
|
|
{
|
|
"user": "root",
|
|
"pid": "4",
|
|
"cpu_percent": "0.0",
|
|
"mem_percent": "0.0",
|
|
"vsz": "0",
|
|
"rss": "0",
|
|
"tty": "?",
|
|
"stat": "S<",
|
|
"start": "Nov09",
|
|
"time": "0:00",
|
|
"command": "[kworker/0:0H]"
|
|
},
|
|
...
|
|
]
|
|
"""
|
|
import jc.utils
|
|
import jc.parsers.universal
|
|
|
|
|
|
class info():
|
|
version = '1.1'
|
|
description = 'ps parser'
|
|
author = 'Kelly Brazil'
|
|
author_email = 'kellyjonbrazil@gmail.com'
|
|
|
|
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
|
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
|
|
|
|
|
def process(proc_data):
|
|
"""
|
|
Final processing to conform to the schema.
|
|
|
|
Parameters:
|
|
|
|
proc_data: (dictionary) raw structured data to process
|
|
|
|
Returns:
|
|
|
|
dictionary structured data with the following schema:
|
|
|
|
[
|
|
{
|
|
"uid": string,
|
|
"pid": integer,
|
|
"ppid": integer,
|
|
"c": integer,
|
|
"stime": string,
|
|
"tty": string, # ? or ?? = Null
|
|
"tt": string, # ?? = Null
|
|
"time": string,
|
|
"cmd": string,
|
|
"user": string,
|
|
"cpu_percent": float,
|
|
"mem_percent": float,
|
|
"vsz": integer,
|
|
"rss": integer,
|
|
"stat": string,
|
|
"start": string,
|
|
"command": string
|
|
}
|
|
]
|
|
"""
|
|
for entry in proc_data:
|
|
# change key name '%cpu' to 'cpu_percent'
|
|
if '%cpu' in entry:
|
|
entry['cpu_percent'] = entry.pop('%cpu')
|
|
|
|
# change key name '%mem' to 'mem_percent'
|
|
if '%mem' in entry:
|
|
entry['mem_percent'] = entry.pop('%mem')
|
|
|
|
# change to int
|
|
int_list = ['pid', 'ppid', 'c', 'vsz', 'rss']
|
|
for key in int_list:
|
|
if key in entry:
|
|
try:
|
|
key_int = int(entry[key])
|
|
entry[key] = key_int
|
|
except (ValueError):
|
|
entry[key] = None
|
|
|
|
# change to float
|
|
float_list = ['cpu_percent', 'mem_percent']
|
|
for key in float_list:
|
|
if key in entry:
|
|
try:
|
|
key_float = float(entry[key])
|
|
entry[key] = key_float
|
|
except (ValueError):
|
|
entry[key] = None
|
|
|
|
if 'tty' in entry:
|
|
if entry['tty'] == '?' or entry['tty'] == '??':
|
|
entry['tty'] = None
|
|
|
|
if 'tt' in entry:
|
|
if entry['tt'] == '??':
|
|
entry['tt'] = None
|
|
|
|
return proc_data
|
|
|
|
|
|
def parse(data, raw=False, quiet=False):
|
|
"""
|
|
Main text parsing function
|
|
|
|
Parameters:
|
|
|
|
data: (string) text data to parse
|
|
raw: (boolean) output preprocessed JSON if True
|
|
quiet: (boolean) suppress warning messages if True
|
|
|
|
Returns:
|
|
|
|
dictionary raw or processed structured data
|
|
"""
|
|
if not quiet:
|
|
jc.utils.compatibility(__name__, info.compatible)
|
|
|
|
cleandata = data.splitlines()
|
|
cleandata[0] = cleandata[0].lower()
|
|
|
|
raw_output = jc.parsers.universal.simple_table_parse(cleandata)
|
|
|
|
if raw:
|
|
return raw_output
|
|
else:
|
|
return process(raw_output)
|