1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-07-15 01:24:29 +02:00

change --time-out to --meta-out. add more meta fields

This commit is contained in:
Kelly Brazil
2022-08-21 12:38:55 -07:00
parent 65cf7960bf
commit 4f21c7b7b4
9 changed files with 65 additions and 44 deletions

View File

@ -280,10 +280,10 @@ option.
| `-d` | `--debug` | Debug mode. Prints trace messages if parsing issues are encountered (use`-dd` for verbose debugging) | | `-d` | `--debug` | Debug mode. Prints trace messages if parsing issues are encountered (use`-dd` for verbose debugging) |
| `-h` | `--help` | Help. Use `jc -h --parser_name` for parser documentation | | `-h` | `--help` | Help. Use `jc -h --parser_name` for parser documentation |
| `-m` | `--monochrome` | Monochrome output | | `-m` | `--monochrome` | Monochrome output |
| `-M` | `--meta-out` | Add metadata to output including timestamp, parser name, magic command, magic command exit code, etc. | |
| `-p` | `--pretty` | Pretty format the JSON output | | `-p` | `--pretty` | Pretty format the JSON output |
| `-q` | `--quiet` | Quiet mode. Suppresses parser warning messages (use `-qq` to ignore streaming parser errors) | | `-q` | `--quiet` | Quiet mode. Suppresses parser warning messages (use `-qq` to ignore streaming parser errors) |
| `-r` | `--raw` | Raw output. Provides more literal output, typically with string values and no additional semantic processing | | `-r` | `--raw` | Raw output. Provides more literal output, typically with string values and no additional semantic processing |
| `-t` | `--time-out` | Add UTC Unix timestamp information to output |
| `-u` | `--unbuffer` | Unbuffer output | | `-u` | `--unbuffer` | Unbuffer output |
| `-v` | `--version` | Version information | | `-v` | `--version` | Version information |
| `-y` | `--yaml-out` | YAML output | | `-y` | `--yaml-out` | YAML output |

View File

@ -5,7 +5,7 @@ _jc()
jc_commands=(acpi airport arp blkid chage cksum crontab date df dig dmidecode dpkg du env file finger free git gpg hciconfig id ifconfig iostat iptables iw jobs last lastb ls lsblk lsmod lsof lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 ufw uname update-alternatives upower uptime vdir vmstat w wc who xrandr zipinfo) jc_commands=(acpi airport arp blkid chage cksum crontab date df dig dmidecode dpkg du env file finger free git gpg hciconfig id ifconfig iostat iptables iw jobs last lastb ls lsblk lsmod lsof lsusb md5 md5sum mdadm mount mpstat netstat nmcli ntpq pidstat ping ping6 pip pip3 postconf printenv ps route rpm rsync sfdisk sha1sum sha224sum sha256sum sha384sum sha512sum shasum ss stat sum sysctl systemctl systeminfo timedatectl top tracepath tracepath6 traceroute traceroute6 ufw uname update-alternatives upower uptime vdir vmstat w wc who xrandr zipinfo)
jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --cef --cef-s --chage --cksum --crontab --crontab-u --csv --csv-s --date --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --finger --free --fstab --git-log --git-log-s --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --iostat --iostat-s --ip-address --iptables --iso-datetime --iw-scan --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsblk --lsmod --lsof --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --passwd --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --ps --route --rpm-qi --rsync --rsync-s --sfdisk --shadow --ss --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --top --top-s --tracepath --traceroute --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --vmstat --vmstat-s --w --wc --who --x509-cert --xml --xrandr --yaml --zipinfo) jc_parsers=(--acpi --airport --airport-s --arp --asciitable --asciitable-m --blkid --cef --cef-s --chage --cksum --crontab --crontab-u --csv --csv-s --date --df --dig --dir --dmidecode --dpkg-l --du --email-address --env --file --finger --free --fstab --git-log --git-log-s --gpg --group --gshadow --hash --hashsum --hciconfig --history --hosts --id --ifconfig --ini --iostat --iostat-s --ip-address --iptables --iso-datetime --iw-scan --jar-manifest --jobs --jwt --kv --last --ls --ls-s --lsblk --lsmod --lsof --lsusb --m3u --mdadm --mount --mpstat --mpstat-s --netstat --nmcli --ntpq --passwd --pidstat --pidstat-s --ping --ping-s --pip-list --pip-show --plist --postconf --ps --route --rpm-qi --rsync --rsync-s --sfdisk --shadow --ss --stat --stat-s --sysctl --syslog --syslog-s --syslog-bsd --syslog-bsd-s --systemctl --systemctl-lj --systemctl-ls --systemctl-luf --systeminfo --time --timedatectl --timestamp --top --top-s --tracepath --traceroute --ufw --ufw-appinfo --uname --update-alt-gs --update-alt-q --upower --uptime --url --vmstat --vmstat-s --w --wc --who --x509-cert --xml --xrandr --yaml --zipinfo)
jc_options=(--force-color -C --debug -d --monochrome -m --pretty -p --quiet -q --raw -r --time-out -t --unbuffer -u --yaml-out -y) jc_options=(--force-color -C --debug -d --monochrome -m --meta-out -M --pretty -p --quiet -q --raw -r --unbuffer -u --yaml-out -y)
jc_about_options=(--about -a) jc_about_options=(--about -a)
jc_about_mod_options=(--pretty -p --yaml-out -y --monochrome -m --force-color -C) jc_about_mod_options=(--pretty -p --yaml-out -y --monochrome -m --force-color -C)
jc_help_options=(--help -h) jc_help_options=(--help -h)

View File

@ -218,7 +218,7 @@ _jc() {
'--yaml:YAML file parser' '--yaml:YAML file parser'
'--zipinfo:`zipinfo` command parser' '--zipinfo:`zipinfo` command parser'
) )
jc_options=(--force-color -C --debug -d --monochrome -m --pretty -p --quiet -q --raw -r --time-out -t --unbuffer -u --yaml-out -y) jc_options=(--force-color -C --debug -d --monochrome -m --meta-out -M --pretty -p --quiet -q --raw -r --unbuffer -u --yaml-out -y)
jc_options_describe=( jc_options_describe=(
'--force-color:force color output even when using pipes (overrides -m)' '--force-color:force color output even when using pipes (overrides -m)'
'-C:force color output even when using pipes (overrides -m)' '-C:force color output even when using pipes (overrides -m)'
@ -226,14 +226,14 @@ _jc() {
'-d:debug (double for verbose debug)' '-d:debug (double for verbose debug)'
'--monochrome:monochrome output' '--monochrome:monochrome output'
'-m:monochrome output' '-m:monochrome output'
'--meta-out:add metadata to output including timestamp, etc.'
'-M:add metadata to output including timestamp, etc.'
'--pretty:pretty print output' '--pretty:pretty print output'
'-p:pretty print output' '-p:pretty print output'
'--quiet:suppress warnings (double to ignore streaming errors)' '--quiet:suppress warnings (double to ignore streaming errors)'
'-q:suppress warnings (double to ignore streaming errors)' '-q:suppress warnings (double to ignore streaming errors)'
'--raw:raw output' '--raw:raw output'
'-r:raw output' '-r:raw output'
'--time-out:add UTC Unix timestamp information to output'
'-t:add UTC Unix timestamp information to output'
'--unbuffer:unbuffer output' '--unbuffer:unbuffer output'
'-u:unbuffer output' '-u:unbuffer output'
'--yaml-out:YAML output' '--yaml-out:YAML output'

View File

@ -445,28 +445,41 @@ def combined_exit_code(program_exit=0, jc_exit=0):
return exit_code return exit_code
def add_timestamp_to(list_or_dict, runtime, magic_exit_code): def add_metadata_to(list_or_dict,
runtime=None,
run_command=None,
magic_exit_code=None,
parser_name=None):
""" """
This function mutates a list or dict in place. If the _jc_meta field This function mutates a list or dict in place. If the _jc_meta field
does not already exist, it will be created with the timestamp field. If does not already exist, it will be created with the metadata fields. If
the _jc_meta field already exists, the timestamp will be added to the the _jc_meta field already exists, the metadata fields will be added to
existing object. the existing object.
""" """
run_timestamp = runtime.timestamp() run_timestamp = runtime.timestamp()
timestamp_obj = {'timestamp': run_timestamp}
if not run_command:
magic_exit_code = None
meta_obj = {
'parser': parser_name,
'magic_command': run_command,
'magic_command_exit': magic_exit_code,
'timestamp': run_timestamp
}
if isinstance(list_or_dict, dict): if isinstance(list_or_dict, dict):
if '_jc_meta' not in list_or_dict: if '_jc_meta' not in list_or_dict:
list_or_dict['_jc_meta'] = {} list_or_dict['_jc_meta'] = {}
list_or_dict['_jc_meta'].update(timestamp_obj) list_or_dict['_jc_meta'].update(meta_obj)
elif isinstance(list_or_dict, list): elif isinstance(list_or_dict, list):
for item in list_or_dict: for item in list_or_dict:
if '_jc_meta' not in item: if '_jc_meta' not in item:
item['_jc_meta'] = {} item['_jc_meta'] = {}
item['_jc_meta'].update(timestamp_obj) item['_jc_meta'].update(meta_obj)
else: else:
utils.error_message(['Parser returned an unsupported object type.']) utils.error_message(['Parser returned an unsupported object type.'])
@ -517,7 +530,7 @@ def main():
quiet = 'q' in options quiet = 'q' in options
ignore_exceptions = options.count('q') > 1 ignore_exceptions = options.count('q') > 1
raw = 'r' in options raw = 'r' in options
timestamp = 't' in options meta_out = 'M' in options
unbuffer = 'u' in options unbuffer = 'u' in options
version_info = 'v' in options version_info = 'v' in options
yaml_out = 'y' in options yaml_out = 'y' in options
@ -632,9 +645,9 @@ def main():
ignore_exceptions=ignore_exceptions) ignore_exceptions=ignore_exceptions)
for line in result: for line in result:
if timestamp: if meta_out:
run_dt_utc = datetime.now(timezone.utc) run_dt_utc = datetime.now(timezone.utc)
add_timestamp_to(line, run_dt_utc, magic_exit_code) add_metadata_to(line, run_dt_utc, run_command, magic_exit_code, parser_name)
safe_print_out(line, safe_print_out(line,
pretty=pretty, pretty=pretty,
@ -661,9 +674,9 @@ def main():
raw=raw, raw=raw,
quiet=quiet) quiet=quiet)
if timestamp: if meta_out:
run_dt_utc = datetime.now(timezone.utc) run_dt_utc = datetime.now(timezone.utc)
add_timestamp_to(result, run_dt_utc, magic_exit_code) add_metadata_to(result, run_dt_utc, run_command, magic_exit_code, parser_name)
safe_print_out(result, safe_print_out(result,
pretty=pretty, pretty=pretty,

View File

@ -7,10 +7,10 @@ long_options_map: Dict[str, List[str]] = {
'--debug': ['d', 'debug (double for verbose debug)'], '--debug': ['d', 'debug (double for verbose debug)'],
'--help': ['h', 'help (--help --parser_name for parser documentation)'], '--help': ['h', 'help (--help --parser_name for parser documentation)'],
'--monochrome': ['m', 'monochrome output'], '--monochrome': ['m', 'monochrome output'],
'--meta-out': ['M', 'add metadata to output including timestamp, etc.'],
'--pretty': ['p', 'pretty print output'], '--pretty': ['p', 'pretty print output'],
'--quiet': ['q', 'suppress warnings (double to ignore streaming errors)'], '--quiet': ['q', 'suppress warnings (double to ignore streaming errors)'],
'--raw': ['r', 'raw output'], '--raw': ['r', 'raw output'],
'--time-out': ['t', 'add UTC Unix timestamp information to output'],
'--unbuffer': ['u', 'unbuffer output'], '--unbuffer': ['u', 'unbuffer output'],
'--version': ['v', 'version info'], '--version': ['v', 'version info'],
'--yaml-out': ['y', 'YAML output'], '--yaml-out': ['y', 'YAML output'],

View File

@ -1,4 +1,4 @@
.TH jc 1 2022-08-20 1.21.0 "JSON Convert" .TH jc 1 2022-08-21 1.21.0 "JSON Convert"
.SH NAME .SH NAME
\fBjc\fP \- JSON Convert JSONifies the output of many CLI tools and file-types \fBjc\fP \- JSON Convert JSONifies the output of many CLI tools and file-types
.SH SYNOPSIS .SH SYNOPSIS
@ -646,6 +646,10 @@ Help (\fB--help --parser_name\fP for parser documentation)
Monochrome output Monochrome output
.TP .TP
.B .B
\fB-M\fP, \fB--meta-out\fP
Add metadata to output including timestamp, parser name, magic command, magic command exit code, etc.
.TP
.B
\fB-p\fP, \fB--pretty\fP \fB-p\fP, \fB--pretty\fP
Pretty print output Pretty print output
.TP .TP
@ -658,10 +662,6 @@ Quiet mode. Suppresses parser warning messages (use -qq to ignore streaming pars
Raw output. Provides more literal output, typically with string values and no additional semantic processing Raw output. Provides more literal output, typically with string values and no additional semantic processing
.TP .TP
.B .B
\fB-t\fP, \fB--time-out\fP
Add UTC Unix timestamp information to output
.TP
.B
\fB-u\fP, \fB--unbuffer\fP \fB-u\fP, \fB--unbuffer\fP
Unbuffer output (useful for slow streaming data with streaming parsers) Unbuffer output (useful for slow streaming data with streaming parsers)
.TP .TP

View File

@ -51,6 +51,10 @@ Help (\fB--help --parser_name\fP for parser documentation)
Monochrome output Monochrome output
.TP .TP
.B .B
\fB-M\fP, \fB--meta-out\fP
Add metadata to output including timestamp, parser name, magic command, magic command exit code, etc.
.TP
.B
\fB-p\fP, \fB--pretty\fP \fB-p\fP, \fB--pretty\fP
Pretty print output Pretty print output
.TP .TP
@ -63,10 +67,6 @@ Quiet mode. Suppresses parser warning messages (use -qq to ignore streaming pars
Raw output. Provides more literal output, typically with string values and no additional semantic processing Raw output. Provides more literal output, typically with string values and no additional semantic processing
.TP .TP
.B .B
\fB-t\fP, \fB--time-out\fP
Add UTC Unix timestamp information to output
.TP
.B
\fB-u\fP, \fB--unbuffer\fP \fB-u\fP, \fB--unbuffer\fP
Unbuffer output (useful for slow streaming data with streaming parsers) Unbuffer output (useful for slow streaming data with streaming parsers)
.TP .TP

View File

@ -161,10 +161,10 @@ option.
| `-d` | `--debug` | Debug mode. Prints trace messages if parsing issues are encountered (use`-dd` for verbose debugging) | | `-d` | `--debug` | Debug mode. Prints trace messages if parsing issues are encountered (use`-dd` for verbose debugging) |
| `-h` | `--help` | Help. Use `jc -h --parser_name` for parser documentation | | `-h` | `--help` | Help. Use `jc -h --parser_name` for parser documentation |
| `-m` | `--monochrome` | Monochrome output | | `-m` | `--monochrome` | Monochrome output |
| `-M` | `--meta-out` | Add metadata to output including timestamp, parser name, magic command, magic command exit code, etc. | |
| `-p` | `--pretty` | Pretty format the JSON output | | `-p` | `--pretty` | Pretty format the JSON output |
| `-q` | `--quiet` | Quiet mode. Suppresses parser warning messages (use `-qq` to ignore streaming parser errors) | | `-q` | `--quiet` | Quiet mode. Suppresses parser warning messages (use `-qq` to ignore streaming parser errors) |
| `-r` | `--raw` | Raw output. Provides more literal output, typically with string values and no additional semantic processing | | `-r` | `--raw` | Raw output. Provides more literal output, typically with string values and no additional semantic processing |
| `-t` | `--time-out` | Add UTC Unix timestamp information to output |
| `-u` | `--unbuffer` | Unbuffer output | | `-u` | `--unbuffer` | Unbuffer output |
| `-v` | `--version` | Version information | | `-v` | `--version` | Version information |
| `-y` | `--yaml-out` | YAML output | | `-y` | `--yaml-out` | YAML output |

View File

@ -255,39 +255,47 @@ class MyTests(unittest.TestCase):
self.assertGreaterEqual(jc.cli.about_jc()['parser_count'], 55) self.assertGreaterEqual(jc.cli.about_jc()['parser_count'], 55)
self.assertEqual(jc.cli.about_jc()['parser_count'], len(jc.cli.about_jc()['parsers'])) self.assertEqual(jc.cli.about_jc()['parser_count'], len(jc.cli.about_jc()['parsers']))
def test_add_timestamp_to_simple_dict(self): def test_add_meta_to_simple_dict(self):
list_or_dict = {'a': 1, 'b': 2} list_or_dict = {'a': 1, 'b': 2}
runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc) runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc)
magic_exit_code = 0 magic_exit_code = 2
expected = {'a': 1, 'b': 2, '_jc_meta': {'timestamp': 1659659829.273349}} run_command = ['ping', '-c3', '192.168.1.123']
jc.cli.add_timestamp_to(list_or_dict, runtime, magic_exit_code) parser_name = 'ping'
expected = {'a': 1, 'b': 2, '_jc_meta': {'parser': 'ping', 'magic_command': ['ping', '-c3', '192.168.1.123'], 'magic_command_exit': 2, 'timestamp': 1659659829.273349}}
jc.cli.add_metadata_to(list_or_dict, runtime, run_command, magic_exit_code, parser_name)
self.assertEqual(list_or_dict, expected) self.assertEqual(list_or_dict, expected)
def test_add_timestamp_to_simple_list(self): def test_add_meta_to_simple_list(self):
list_or_dict = [{'a': 1, 'b': 2},{'a': 3, 'b': 4}] list_or_dict = [{'a': 1, 'b': 2},{'a': 3, 'b': 4}]
runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc) runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc)
magic_exit_code = 0 magic_exit_code = 2
expected = [{'a': 1, 'b': 2, '_jc_meta': {'timestamp': 1659659829.273349}}, {'a': 3, 'b': 4, '_jc_meta': {'timestamp': 1659659829.273349}}] run_command = ['ping', '-c3', '192.168.1.123']
jc.cli.add_timestamp_to(list_or_dict, runtime, magic_exit_code) parser_name = 'ping'
expected = [{'a': 1, 'b': 2, '_jc_meta': {'parser': 'ping', 'magic_command': ['ping', '-c3', '192.168.1.123'], 'magic_command_exit': 2, 'timestamp': 1659659829.273349}}, {'a': 3, 'b': 4, '_jc_meta': {'parser': 'ping', 'magic_command': ['ping', '-c3', '192.168.1.123'], 'magic_command_exit': 2, 'timestamp': 1659659829.273349}}]
jc.cli.add_metadata_to(list_or_dict, runtime, run_command, magic_exit_code, parser_name)
self.assertEqual(list_or_dict, expected) self.assertEqual(list_or_dict, expected)
def test_add_timestamp_to_dict_existing_meta(self): def test_add_meta_to_dict_existing_meta(self):
list_or_dict = {'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar'}} list_or_dict = {'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar'}}
runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc) runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc)
magic_exit_code = 0 magic_exit_code = 2
expected = {'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar', 'timestamp': 1659659829.273349}} run_command = ['ping', '-c3', '192.168.1.123']
jc.cli.add_timestamp_to(list_or_dict, runtime, magic_exit_code) parser_name = 'ping'
expected = {'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar', 'parser': 'ping', 'magic_command': ['ping', '-c3', '192.168.1.123'], 'magic_command_exit': 2, 'timestamp': 1659659829.273349}}
jc.cli.add_metadata_to(list_or_dict, runtime, run_command, magic_exit_code, parser_name)
self.assertEqual(list_or_dict, expected) self.assertEqual(list_or_dict, expected)
def test_add_timestamp_to_list_existing_meta(self): def test_add_meta_to_list_existing_meta(self):
list_or_dict = [{'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar'}},{'a': 3, 'b': 4, '_jc_meta': {'foo': 'bar'}}] list_or_dict = [{'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar'}},{'a': 3, 'b': 4, '_jc_meta': {'foo': 'bar'}}]
runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc) runtime = datetime(2022, 8, 5, 0, 37, 9, 273349, tzinfo=timezone.utc)
magic_exit_code = 0 magic_exit_code = 2
expected = [{'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar', 'timestamp': 1659659829.273349}}, {'a': 3, 'b': 4, '_jc_meta': {'foo': 'bar', 'timestamp': 1659659829.273349}}] run_command = ['ping', '-c3', '192.168.1.123']
jc.cli.add_timestamp_to(list_or_dict, runtime, magic_exit_code) parser_name = 'ping'
expected = [{'a': 1, 'b': 2, '_jc_meta': {'foo': 'bar', 'parser': 'ping', 'magic_command': ['ping', '-c3', '192.168.1.123'], 'magic_command_exit': 2, 'timestamp': 1659659829.273349}}, {'a': 3, 'b': 4, '_jc_meta': {'foo': 'bar', 'parser': 'ping', 'magic_command': ['ping', '-c3', '192.168.1.123'], 'magic_command_exit': 2, 'timestamp': 1659659829.273349}}]
jc.cli.add_metadata_to(list_or_dict, runtime, run_command, magic_exit_code, parser_name)
self.assertEqual(list_or_dict, expected) self.assertEqual(list_or_dict, expected)