Postmortem dump analyzer tool

I wrote a script that reconstructs an application-level view of network activities based on a low-level network dump file; this is a significant usability improvement on top of the old post Postmortem debugging with Yakut. Currently, it only supports candump log files because that’s what I needed it for, but it is trivial to extend to also support tcpdump files or whatever custom format is needed — it is super simple to create a custom parser following the candump example. Heterogeneously redundant transports are also supported by design although I didn’t test it yet.

The script currently consists of two files – the script body itself and dtype_loader.py which has been pulled straight from Yakut:

cyroner.py (12.5 KB)
dtype_loader.py (4.9 KB)

Usage:

./cyroner.py  candump.log  408:uavcan.file.Read  435:uavcan.node.ExecuteCommand  >output.json

Specify the port-ID to data type mappings following the example. Any number of input log files are supported; the tool uses a simple heuristic to tell log file names apart from port-ID mappings. Use -v for verbosity to see what’s up.

Feed the output through jq to filter specific messages or fields of interest. The JSON schema follows the regular Yakut output.

Example output:

{"_meta_": {"ts_system": 1723389566.189359, "ts_monotonic": 892858.413041906, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 4, "source_node_id": 0, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "44000000000000"}, "uptime": 68, "health": {"value": 0}, "mode": {"value": 0}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389566.189696, "ts_monotonic": 892858.413295218, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}
{"_meta_": {"ts_system": 1723389566.979682, "ts_monotonic": 892858.413419143, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 16, "source_node_id": 10, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "65000000000300"}, "uptime": 101, "health": {"value": 0}, "mode": {"value": 3}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389566.979701, "ts_monotonic": 892858.413632113, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 4, "source_node_id": 10, "destination_node_id": null, "subject_id": 1001, "dtype": null, "payload_hex": "00000000000000"}}
{"_meta_": {"ts_system": 1723389567.189687, "ts_monotonic": 892858.41376303, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 5, "source_node_id": 0, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "45000000000000"}, "uptime": 69, "health": {"value": 0}, "mode": {"value": 0}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389567.190046, "ts_monotonic": 892858.413962314, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}
{"_meta_": {"ts_system": 1723389567.980684, "ts_monotonic": 892858.414101779, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 5, "source_node_id": 10, "destination_node_id": null, "subject_id": 1001, "dtype": null, "payload_hex": "00000000000000"}}
{"_meta_": {"ts_system": 1723389567.982613, "ts_monotonic": 892858.414235632, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 17, "source_node_id": 10, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "66000000000300"}, "uptime": 102, "health": {"value": 0}, "mode": {"value": 3}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389568.189987, "ts_monotonic": 892858.414504125, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 6, "source_node_id": 0, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "46000000000000"}, "uptime": 70, "health": {"value": 0}, "mode": {"value": 0}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389568.190366, "ts_monotonic": 892858.414711465, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}
{"_meta_": {"ts_system": 1723389569.003684, "ts_monotonic": 892858.414888167, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 18, "source_node_id": 10, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "67000000000300"}, "uptime": 103, "health": {"value": 0}, "mode": {"value": 3}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389569.005667, "ts_monotonic": 892858.415101827, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 6, "source_node_id": 10, "destination_node_id": null, "subject_id": 1001, "dtype": null, "payload_hex": "00000000000000"}}
{"_meta_": {"ts_system": 1723389569.008608, "ts_monotonic": 892858.415475236, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "slow", "transfer_id": 15, "source_node_id": 10, "destination_node_id": 0, "service_id": 408, "role": "request", "dtype": "uavcan.file.Read.Request.1.1", "payload_hex": "000e0000000d746f6f2d6c617267652e62696e"}, "offset": 3584, "path": {"path": "too-large.bin"}}
{"_meta_": {"ts_system": 1723389569.015668, "ts_monotonic": 892858.417768803, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "slow", "transfer_id": 15, "source_node_id": 0, "destination_node_id": 10, "service_id": 408, "role": "response", "dtype": "uavcan.file.Read.Response.1.1", "payload_hex": "000000013632555f53535526665d2c6344566f3a433266305c66265b235f5c6147234c546d3d52473a7a4b2b2e4635536d6e416179505f61557452414b4a66312e47542d2d5667457b6d757d42376e7d79503c402a4e60725d3d6b227b6b6352323e30633b5a2f307a67493d542a7053256b3e2a55676b49777a23317d5e5c2d2f327c64507c5a25655931482f535564687078425f323847394d5043372c4a2c6c774a426a335b304d4933782e642b23285b45396461386f7e49462b2e62754d225e535064754e697d4136723e3e6f6b2568536c41293541515a795c4c3a5423625d3a4e273e4e67763078212c7428654935236e37396e294b2d5e4e6e6f70315568773f"}, "error": {"value": 0}, "data": {"value": "62U_SSU&f],cDVo:C2f0\\f&[#_\\aG#LTm=RG:zK+.F5SmnAayP_aUtRAKJf1.GT--VgE{mu}B7n}yP<@*N`r]=k\"{kcR2>0c;Z/0zgI=T*pS%k>*UgkIwz#1}^\\-/2|dP|Z%eY1H/SUdhpxB_28G9MPC7,J,lwJBj3[0MI3x.d+#([E9da8o~IF+.buM\"^SPduNi}A6r>>ok%hSlA)5AQZy\\L:T#b]:N'>Ngv0x!,t(eI5#n79n)K-^Nnop1Uhw?"}}
{"_meta_": {"ts_system": 1723389569.021015, "ts_monotonic": 892858.420158294, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}
{"_meta_": {"ts_system": 1723389569.189503, "ts_monotonic": 892858.420286629, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 7, "source_node_id": 0, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "47000000000000"}, "uptime": 71, "health": {"value": 0}, "mode": {"value": 0}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389569.189837, "ts_monotonic": 892858.420486126, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}
{"_meta_": {"ts_system": 1723389570.005679, "ts_monotonic": 892858.42060722, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 19, "source_node_id": 10, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "68000000000300"}, "uptime": 104, "health": {"value": 0}, "mode": {"value": 3}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389570.006625, "ts_monotonic": 892858.420818083, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 7, "source_node_id": 10, "destination_node_id": null, "subject_id": 1001, "dtype": null, "payload_hex": "00000000000000"}}
{"_meta_": {"ts_system": 1723389570.189993, "ts_monotonic": 892858.42094911, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 8, "source_node_id": 0, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "48000000000000"}, "uptime": 72, "health": {"value": 0}, "mode": {"value": 0}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389570.190352, "ts_monotonic": 892858.421147629, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}
{"_meta_": {"ts_system": 1723389571.006683, "ts_monotonic": 892858.42126878, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 20, "source_node_id": 10, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "69000000000300"}, "uptime": 105, "health": {"value": 0}, "mode": {"value": 3}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389571.008614, "ts_monotonic": 892858.421465346, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 8, "source_node_id": 10, "destination_node_id": null, "subject_id": 1001, "dtype": null, "payload_hex": "00000000000000"}}
{"_meta_": {"ts_system": 1723389571.189791, "ts_monotonic": 892858.421593855, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "nominal", "transfer_id": 9, "source_node_id": 0, "destination_node_id": null, "subject_id": 7509, "dtype": "uavcan.node.Heartbeat.1.0", "payload_hex": "49000000000000"}, "uptime": 73, "health": {"value": 0}, "mode": {"value": 0}, "vendor_specific_status_code": 0}
{"_meta_": {"ts_system": 1723389571.190134, "ts_monotonic": 892858.421792425, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}
{"_meta_": {"ts_system": 1723389571.432632, "ts_monotonic": 892858.422031692, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "slow", "transfer_id": 16, "source_node_id": 10, "destination_node_id": 0, "service_id": 408, "role": "request", "dtype": "uavcan.file.Read.Request.1.1", "payload_hex": "000f0000000d746f6f2d6c617267652e62696e"}, "offset": 3840, "path": {"path": "too-large.bin"}}
{"_meta_": {"ts_system": 1723389571.439878, "ts_monotonic": 892858.424356746, "transport": {"kind": "can", "source_iface": "slcan0"}, "priority": "slow", "transfer_id": 16, "source_node_id": 0, "destination_node_id": 10, "service_id": 408, "role": "response", "dtype": "uavcan.file.Read.Response.1.1", "payload_hex": "0000000171717c5d5a606a617b334075402c4722394258657c4e2a75452b6a7153595842614d7b4c5c3c7a7e716a30533462513225615f5d325b4a676074453d7b2662577444685c7921634c6b7178782c545f61567a7d6f61742d46574e4b3226752e7731326f5c2a5543564b412262793525285d7b29715f563b7a3c554668625a2b5d2576657b7e45335442347e4763327c48735848775931223d21254f2f6b437a51553a53345e734f3b3c2e525e7d666b4a3f606073725f5046424325352268505e422f27345d444a2b4f7c2b5265472d304a2b503e7d5f5a56677421244255586c6d623f4170502f71715f215c5d7c2c795c4460773a5a533a714c7b377d482f68"}, "error": {"value": 0}, "data": {"value": "qq|]Z`ja{3@u@,G\"9BXe|N*uE+jqSYXBaM{L\\<z~qj0S4bQ2%a_]2[Jg`tE={&bWtDh\\y!cLkqxx,T_aVz}oat-FWNK2&u.w12o\\*UCVKA\"by5%(]{)q_V;z<UFhbZ+]%ve{~E3TB4~Gc2|HsXHwY1\"=!%O/kCzQU:S4^sO;<.R^}fkJ?``sr_PFBC%5\"hP^B/'4]DJ+O|+ReG-0J+P>}_ZVgt!$BUXlmb?ApP/qq_!\\]|,y\\D`w:ZS:qL{7}H/h"}}
{"_meta_": {"ts_system": 1723389571.444961, "ts_monotonic": 892858.426654751, "transport": {"kind": "can", "source_iface": "slcan1"}, "duplicate": {}}}

I will be incorporating this script into Yakut as a separate command at one point.