diff --git a/CHANGELOG b/CHANGELOG index f1e6a760..7353e840 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,7 @@ jc changelog - Update stat parser to add access_time_epoch, access_time_epoch_utc, modify_time_epoch, modify_time_epoch_utc, change_time_epoch, change_time_epoch_utc, birth_time_epoch, birth_time_epoch_utc fields - Update timedatectl parser to add epoch_utc field +- Update who parser to add epoch field - Add -h option to display the help text. Piping errors no longer show the help text. - Add -v option to display version information. - Make all external python library dependencies optional: pygments, ruamel.yaml, xmltodict diff --git a/EXAMPLES.md b/EXAMPLES.md index fad038c4..a1d2c8f5 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -2950,13 +2950,15 @@ who | jc --who -p # or: jc -p who { "user": "joeuser", "tty": "ttyS0", - "time": "2020-03-02 02:52" + "time": "2020-03-02 02:52", + "epoch": 1583146320 }, { "user": "joeuser", "tty": "pts/0", "time": "2020-03-02 05:15", - "from": "192.168.71.1" + "from": "192.168.71.1", + "epoch": 1583154900 } ] ``` @@ -2968,32 +2970,8 @@ who -a | jc --who -p # or: jc -p who -a { "event": "reboot", "time": "Feb 7 23:31", - "pid": 1 - }, - { - "user": "joeuser", - "writeable_tty": "-", - "tty": "console", - "time": "Feb 7 23:32", - "idle": "old", - "pid": 105 - }, - { - "user": "joeuser", - "writeable_tty": "+", - "tty": "ttys000", - "time": "Feb 13 16:44", - "idle": ".", - "pid": 51217, - "comment": "term=0 exit=0" - }, - { - "user": "joeuser", - "writeable_tty": "?", - "tty": "ttys003", - "time": "Feb 28 08:59", - "idle": "01:36", - "pid": 41402 + "pid": 1, + "epoch": null }, { "user": "joeuser", @@ -3002,7 +2980,8 @@ who -a | jc --who -p # or: jc -p who -a "time": "Mar 1 16:35", "idle": ".", "pid": 15679, - "from": "192.168.1.5" + "from": "192.168.1.5", + "epoch": null } ] ``` diff --git a/docs/parsers/who.md b/docs/parsers/who.md index 245a62a4..0dfe152c 100644 --- a/docs/parsers/who.md +++ b/docs/parsers/who.md @@ -4,6 +4,8 @@ jc - JSON CLI output utility `who` command output parser Accepts any of the following who options (or no options): `-aTH` +The `epoch` calculated timestamp field is naive (i.e. based on the local time of the system the parser is run on) + Usage (cli): $ who | jc --who @@ -28,7 +30,8 @@ Examples: { "event": "reboot", "time": "Feb 7 23:31", - "pid": 1 + "pid": 1, + "epoch": null }, { "user": "joeuser", @@ -36,7 +39,8 @@ Examples: "tty": "console", "time": "Feb 7 23:32", "idle": "old", - "pid": 105 + "pid": 105, + "epoch": null }, { "user": "joeuser", @@ -45,7 +49,8 @@ Examples: "time": "Feb 13 16:44", "idle": ".", "pid": 51217, - "comment": "term=0 exit=0" + "comment": "term=0 exit=0", + "epoch": null }, { "user": "joeuser", @@ -53,7 +58,8 @@ Examples: "tty": "ttys003", "time": "Feb 28 08:59", "idle": "01:36", - "pid": 41402 + "pid": 41402, + "epoch": null }, { "user": "joeuser", @@ -62,7 +68,8 @@ Examples: "time": "Mar 1 16:35", "idle": ".", "pid": 15679, - "from": "192.168.1.5" + "from": "192.168.1.5", + "epoch": null } ] @@ -138,6 +145,7 @@ Returns: "writeable_tty": string, "tty": string, "time": string, + "epoch": integer, # naive timestamp. null if time cannot be converted "idle": string, "pid": integer, "from": string, diff --git a/jc/parsers/who.py b/jc/parsers/who.py index a91da148..9d65dc98 100644 --- a/jc/parsers/who.py +++ b/jc/parsers/who.py @@ -2,6 +2,8 @@ Accepts any of the following who options (or no options): `-aTH` +The `epoch` calculated timestamp field is naive (i.e. based on the local time of the system the parser is run on) + Usage (cli): $ who | jc --who @@ -26,7 +28,8 @@ Examples: { "event": "reboot", "time": "Feb 7 23:31", - "pid": 1 + "pid": 1, + "epoch": null }, { "user": "joeuser", @@ -34,7 +37,8 @@ Examples: "tty": "console", "time": "Feb 7 23:32", "idle": "old", - "pid": 105 + "pid": 105, + "epoch": null }, { "user": "joeuser", @@ -43,7 +47,8 @@ Examples: "time": "Feb 13 16:44", "idle": ".", "pid": 51217, - "comment": "term=0 exit=0" + "comment": "term=0 exit=0", + "epoch": null }, { "user": "joeuser", @@ -51,7 +56,8 @@ Examples: "tty": "ttys003", "time": "Feb 28 08:59", "idle": "01:36", - "pid": 41402 + "pid": 41402, + "epoch": null }, { "user": "joeuser", @@ -60,7 +66,8 @@ Examples: "time": "Mar 1 16:35", "idle": ".", "pid": 15679, - "from": "192.168.1.5" + "from": "192.168.1.5", + "epoch": null } ] @@ -112,7 +119,7 @@ import jc.utils class info(): - version = '1.1' + version = '1.2' description = 'who command parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -145,6 +152,7 @@ def process(proc_data): "writeable_tty": string, "tty": string, "time": string, + "epoch": integer, # naive timestamp. null if time cannot be converted "idle": string, "pid": integer, "from": string, @@ -162,6 +170,9 @@ def process(proc_data): except (ValueError): entry[key] = None + if 'time' in entry: + entry['epoch'] = jc.utils.parse_datetime_to_timestamp(entry['time'])['timestamp_naive'] + return proc_data diff --git a/jc/utils.py b/jc/utils.py index 570ec3cf..f584e277 100644 --- a/jc/utils.py +++ b/jc/utils.py @@ -135,6 +135,7 @@ def parse_datetime_to_timestamp(data): formats = [ {'id': 1000, 'format': '%a %b %d %H:%M:%S %Y', 'locale': None}, # manual C locale format conversion: Tue Mar 23 16:12:11 2021 or Tue Mar 23 16:12:11 IST 2021 + {'id': 1500, 'format': '%Y-%m-%d %H:%M', 'locale': None}, # en_US.UTF-8 local format (found in who cli output): 2021-03-23 00:14 {'id': 2000, 'format': '%a %d %b %Y %I:%M:%S %p %Z', 'locale': None}, # en_US.UTF-8 local format (found in upower cli output): Tue 23 Mar 2021 04:12:11 PM UTC {'id': 3000, 'format': '%a %d %b %Y %I:%M:%S %p', 'locale': None}, # en_US.UTF-8 local format with non-UTC tz (found in upower cli output): Tue 23 Mar 2021 04:12:11 PM IST {'id': 4000, 'format': '%A %d %B %Y %I:%M:%S %p %Z', 'locale': None}, # European-style local format (found in upower cli output): Tuesday 01 October 2019 12:50:41 PM UTC diff --git a/tests/fixtures/centos-7.7/who-a.json b/tests/fixtures/centos-7.7/who-a.json index d691e692..e8a039a9 100644 --- a/tests/fixtures/centos-7.7/who-a.json +++ b/tests/fixtures/centos-7.7/who-a.json @@ -1 +1 @@ -[{"event": "reboot", "time": "2020-02-29 12:13"}, {"event": "login", "tty": "tty1", "time": "2020-02-29 12:13", "pid": 841, "comment": "id=tty1"}, {"user": "kbrazil", "writeable_tty": "+", "tty": "ttyS0", "time": "2020-02-29 12:14", "idle": ".", "pid": 840}, {"event": "run-level 3", "time": "2020-02-29 12:13"}, {"user": "kbrazil", "writeable_tty": "+", "tty": "pts/0", "time": "2020-02-29 18:43", "idle": "00:11", "pid": 3709, "from": "192.168.71.1"}, {"tty": "pts/1", "time": "2020-02-29 18:28", "pid": 3381, "comment": "id=ts/1 term=0 exit=0"}] +[{"event":"reboot","time":"2020-02-29 12:13","epoch":1583007180},{"event":"login","tty":"tty1","time":"2020-02-29 12:13","pid":841,"comment":"id=tty1","epoch":1583007180},{"user":"kbrazil","writeable_tty":"+","tty":"ttyS0","time":"2020-02-29 12:14","idle":".","pid":840,"epoch":1583007240},{"event":"run-level 3","time":"2020-02-29 12:13","epoch":1583007180},{"user":"kbrazil","writeable_tty":"+","tty":"pts/0","time":"2020-02-29 18:43","idle":"00:11","pid":3709,"from":"192.168.71.1","epoch":1583030580},{"tty":"pts/1","time":"2020-02-29 18:28","pid":3381,"comment":"id=ts/1 term=0 exit=0","epoch":1583029680}] diff --git a/tests/fixtures/centos-7.7/who.json b/tests/fixtures/centos-7.7/who.json index 30f57713..16e34fd8 100644 --- a/tests/fixtures/centos-7.7/who.json +++ b/tests/fixtures/centos-7.7/who.json @@ -1 +1 @@ -[{"user": "kbrazil", "tty": "ttyS0", "time": "2020-02-29 12:14"}, {"user": "kbrazil", "tty": "pts/0", "time": "2020-02-29 18:43", "from": "192.168.71.1"}] +[{"user":"kbrazil","tty":"ttyS0","time":"2020-02-29 12:14","epoch":1583007240},{"user":"kbrazil","tty":"pts/0","time":"2020-02-29 18:43","from":"192.168.71.1","epoch":1583030580}] diff --git a/tests/fixtures/osx-10.14.6/who-a.json b/tests/fixtures/osx-10.14.6/who-a.json index d43d5a6c..61b5008a 100644 --- a/tests/fixtures/osx-10.14.6/who-a.json +++ b/tests/fixtures/osx-10.14.6/who-a.json @@ -1 +1 @@ -[{"event": "reboot", "time": "Feb 7 23:31", "pid": 1}, {"user": "kbrazil", "tty": "console", "time": "Feb 7 23:32", "idle": "old", "pid": 105}, {"user": "kbrazil", "tty": "ttys000", "time": "Feb 13 16:44", "idle": "00:02", "pid": 51217, "comment": "term=0 exit=0"}, {"user": "kbrazil", "tty": "ttys001", "time": "Feb 11 21:25", "idle": "00:02", "pid": 81390}, {"user": "kbrazil", "tty": "ttys002", "time": "Mar 1 15:18", "idle": ".", "pid": 9574}, {"user": "kbrazil", "tty": "ttys003", "time": "Feb 28 08:59", "idle": "01:06", "pid": 41402}, {"user": "kbrazil", "tty": "ttys004", "time": "Mar 1 17:11", "idle": ".", "pid": 15679, "comment": "term=0 exit=0"}] +[{"event":"reboot","time":"Feb 7 23:31","pid":1,"epoch":null},{"user":"kbrazil","tty":"console","time":"Feb 7 23:32","idle":"old","pid":105,"epoch":null},{"user":"kbrazil","tty":"ttys000","time":"Feb 13 16:44","idle":"00:02","pid":51217,"comment":"term=0 exit=0","epoch":null},{"user":"kbrazil","tty":"ttys001","time":"Feb 11 21:25","idle":"00:02","pid":81390,"epoch":null},{"user":"kbrazil","tty":"ttys002","time":"Mar 1 15:18","idle":".","pid":9574,"epoch":null},{"user":"kbrazil","tty":"ttys003","time":"Feb 28 08:59","idle":"01:06","pid":41402,"epoch":null},{"user":"kbrazil","tty":"ttys004","time":"Mar 1 17:11","idle":".","pid":15679,"comment":"term=0 exit=0","epoch":null}] diff --git a/tests/fixtures/osx-10.14.6/who.json b/tests/fixtures/osx-10.14.6/who.json index 2ffaee92..867e787a 100644 --- a/tests/fixtures/osx-10.14.6/who.json +++ b/tests/fixtures/osx-10.14.6/who.json @@ -1 +1 @@ -[{"user": "kbrazil", "tty": "console", "time": "Feb 7 23:32"}, {"user": "kbrazil", "tty": "ttys001", "time": "Feb 11 21:25"}, {"user": "kbrazil", "tty": "ttys002", "time": "Mar 1 15:18"}, {"user": "kbrazil", "tty": "ttys003", "time": "Feb 28 08:59"}] +[{"user":"kbrazil","tty":"console","time":"Feb 7 23:32","epoch":null},{"user":"kbrazil","tty":"ttys001","time":"Feb 11 21:25","epoch":null},{"user":"kbrazil","tty":"ttys002","time":"Mar 1 15:18","epoch":null},{"user":"kbrazil","tty":"ttys003","time":"Feb 28 08:59","epoch":null}] diff --git a/tests/fixtures/ubuntu-18.04/who-a.json b/tests/fixtures/ubuntu-18.04/who-a.json index 714a8460..4979e8e6 100644 --- a/tests/fixtures/ubuntu-18.04/who-a.json +++ b/tests/fixtures/ubuntu-18.04/who-a.json @@ -1 +1 @@ -[{"event": "reboot", "time": "2020-03-02 02:52"}, {"user": "kbrazil", "writeable_tty": "-", "tty": "ttyS0", "time": "2020-03-02 02:52", "idle": ".", "pid": 1983}, {"event": "run-level 5", "time": "2020-03-02 02:52"}, {"event": "login", "tty": "tty1", "time": "2020-03-02 02:52", "pid": 1199, "comment": "id=tty1"}, {"user": "kbrazil", "writeable_tty": "+", "tty": "pts/0", "time": "2020-03-02 02:54", "idle": ".", "pid": 2176, "from": "192.168.71.1"}] +[{"event":"reboot","time":"2020-03-02 02:52","epoch":1583146320},{"user":"kbrazil","writeable_tty":"-","tty":"ttyS0","time":"2020-03-02 02:52","idle":".","pid":1983,"epoch":1583146320},{"event":"run-level 5","time":"2020-03-02 02:52","epoch":1583146320},{"event":"login","tty":"tty1","time":"2020-03-02 02:52","pid":1199,"comment":"id=tty1","epoch":1583146320},{"user":"kbrazil","writeable_tty":"+","tty":"pts/0","time":"2020-03-02 02:54","idle":".","pid":2176,"from":"192.168.71.1","epoch":1583146440}] diff --git a/tests/fixtures/ubuntu-18.04/who.json b/tests/fixtures/ubuntu-18.04/who.json index 060b909d..41b0585f 100644 --- a/tests/fixtures/ubuntu-18.04/who.json +++ b/tests/fixtures/ubuntu-18.04/who.json @@ -1 +1 @@ -[{"user": "kbrazil", "tty": "ttyS0", "time": "2020-03-02 02:52"}, {"user": "kbrazil", "tty": "pts/0", "time": "2020-03-02 02:54", "from": "192.168.71.1"}] +[{"user":"kbrazil","tty":"ttyS0","time":"2020-03-02 02:52","epoch":1583146320},{"user":"kbrazil","tty":"pts/0","time":"2020-03-02 02:54","from":"192.168.71.1","epoch":1583146440}] diff --git a/tests/test_utils.py b/tests/test_utils.py index 342e7da8..f8a7e4b2 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -10,6 +10,8 @@ class MyTests(unittest.TestCase): # C locale format conversion, or date cli command in C locale with non-UTC tz 'Tue Mar 23 16:12:11 2021': {'format': 1000, 'timestamp_naive': 1616541131, 'timestamp_utc': None}, 'Tue Mar 23 16:12:11 IST 2021': {'format': 1000, 'timestamp_naive': 1616541131, 'timestamp_utc': None}, + # en_US.UTF-8 local format (found in who cli output) + '2021-03-23 00:14': {'format': 1500, 'timestamp_naive': 1616483640, 'timestamp_utc': None}, # en_US.UTF-8 local format (found in upower cli output) 'Tue 23 Mar 2021 04:12:11 PM UTC': {'format': 2000, 'timestamp_naive': 1616541131, 'timestamp_utc': 1616515931}, # en_US.UTF-8 local format with non-UTC tz (found in upower cli output)