Built this because I was tired of eyeballing a full log next to a pjsip set logger on dump trying to line up a Dial() with the INVITE/BYE it actually caused.
pbxray parses Asterisk full/messages logs plus pjsip set logger on output into one correlated timeline - dialplan and SIP signalling together, queryable from the terminal. Single static binary, no runtime deps.
$ pbxray ls calls.log --failed
LINKED-ID DATETIME FROM TO CHANNELS DURATION CAUSE
C-00001a2b 2026-07-20 09:12:03 15555550142 15555550199 1 4s 17 (User Busy)
$ pbxray show calls.log C-00001a2b
2026-07-20 09:12:03 dialplan Dial(PJSIP/15555550199@TRUNK,30) on PJSIP/alice-00000001
2026-07-20 09:12:03 sip tx INVITE sip:15555550199@sip.example.com
2026-07-20 09:12:03 sip rx 486 Busy Here
ls for filtering (time range, failed calls, number/DID, endpoint), show for the full timeline, tail -f for live. SIP<->call links that are best-effort guesses get flagged (probable link) rather than presented as fact.
Install:
curl -fsSL https://raw.githubusercontent.com/pbxray/pbxray-dist/main/install.sh | sh
This is why my Seaskirt wrapper for Asterisk APIs includes access to the console API as well. I have an example script somewhere which originates a call, and then monitors both Manager events and console output, with the option to write them (with timestamps) to separate logfiles or to the same logfile.