How to monitor registration status of SIP peers?

Dear all,

I want to monitor the registration status of (PJ)SIP peers providing SIP trunks to an asterisk system.

I would like to do this in a robust / decent way rather than manually parsing the output of asterisk -rx sip show peer.

What would be the state-of-the-art to go here?

Check Device state or use AMI for Real time monitoring from external source

Thanks for your suggestions. I will go for AMI then, since I already use AMI but with rudimentary scripts written with Tcl/Tk’s expect.
I want to go for Python as language, but I did not succeed in having it running so far.

I tried https://github.com/asterisk/starpy. I tried to build the documentation by running doc/pydoc/builddocs.py. The script returns with an error:

Start 'starpy'
   ... found 'starpy'
Traceback (most recent call last):
  File "builddocs.py", line 25, in <module>
    recursionStops=stops,
  File "/root/starpy/doc/pydoc/pydoc2.py", line 402, in process
    packageContext=self,
  File "/root/starpy/doc/pydoc/pydoc2.py", line 159, in docmodule
    for file in os.listdir(object.__path__[0]):
OSError: [Errno 20] Not a directory: '/usr/local/lib/python2.7/dist-packages/starpy-1.0.3-py2.7.egg/starpy'

Apparently, the script assumes the package to be a directory, while it actually is a file.

Furthermore, I tried the examples. The HTML documentation tells utilapplication and basicproperty. The latter apparently is 13 years old and not compatible with Python 2.7:

Collecting basicproperty
  Could not find a version that satisfies the requirement basicproperty (from versions: )
No matching distribution found for basicproperty

I tried to find additional information, the documentation references http://starpy.sourceforge.net, but that has not been updated since 2008.

in the past was looking for similar task : monitor peers registration status.
ended up with a php PAMI script, running on asterisk server and listening to the events, then writes event to the mysql database for reporting and drawing charts with peer presence on a time line ( Used to track working time of the call center operators )

First - configured AMI access ( asterisk/manager.conf) ,
next - created mysql table ‘realstatus’ :

±--------------±-------------±
| Field | Type |
±--------------±-------------±
| id | int(11) |
| ts | timestamp |
| sip_name | varchar(100) |
| event_type | varchar(100) |
| event_data | varchar(100) |
| event_details | varchar(100) |
| session_time | int(11) |
±--------------±-------------±

Script, which attaches to the AMI interface and keep listening events:

<?php 
ini_set('display_errors', 1);
error_reporting(1);


use PAMI\Client\Impl\ClientImpl as PamiClient;  
use PAMI\Message\Event\EventMessage; 
use PAMI\Listener\IEventListener;  
use PAMI\Message\Event\ExtensionStatusEvent;
use PAMI\Message\Event\NewstateEvent;
use PAMI\Message\Event\StatusCompleteEvent;
use PAMI\Message\Event\StatusEvent;
require_once("vendor/autoload.php");

  $pamiClientOptions = array(
    'log4php.properties' => __DIR__ . '/log4php.properties',    
    'host' => 'localhost',  
    'scheme' => 'tcp://',  
    'port' => 5038,  
    'username' => 'pbx-manager-dev',  
    'secret' => 'p_ssw0rd',  
    'connect_timeout' => 100,  
    'read_timeout' => 10000  
    );

   $pamiClient = new PamiClient($pamiClientOptions);  
  
   $mysqli = new mysqli("localhost","asteriskuser","asterpass","asterisk");
   if($mysqli -> connect_errno) 
    die( "Failed to connect to MySQL: " . $mysqli -> connect_error );

  // Open the connection  
  $pamiClient->open();  

  $pamiClient->registerEventListener(
      function (EventMessage $event) {
	GLOBAL $conf;

        $last_event = $event->getKeys();
	$event_type = $last_event["event"];
//	echo 'Got:' . $event_type . "\n";

        preg_match("/SIP\/(.*)\-/", $last_event['channel'] , $m );
        $PEER = $m[1];
  

	switch (true) {

            case $event_type == 'PeerStatus'  :
                catchStatus($last_event,$PEER);
		break;

	    case $event_type == 'Registry':
		 // Peer registration 
               // var_dump($last_event);
                break;

            case $event_type == 'DialState':
                //DialState($last_event,$PEER);
                break;

            case $event_type == 'Newchannel':
                 //NewChannelEvent( $last_event, $PEER);
		 break;
	 
	    case $event_type == 'DialEnd' :
		 //CallEndEvent($last_event,$PEER);

            default:
                # code...
                break;
        }
    }
);  



$running = true; 

while($running) {
    try {
        $pamiClient->process();
    } catch (Exception $e) {
      echo $e->getMessage();   
      exit; // To be restarted
    }
    sleep(1);
     
}  

$pamiClient->close();  

function catchStatus($event,$PEER){
	global $mysqli;

	echo '[' . date("M j G:i:s Y") . "]  "  . $event['event'] . ':  ' . $event['peer'] . '  :  ' . $event['peerstatus'] . '  ' . $event['cause'] ;
	$mysqli->query("INSERT INTO realstatus(sip_name, event_type, event_data ) 
		    VALUES('{$event['peer']}',
                           '{$event['event']}',
			   '{$event['peerstatus']}'			   
			   )") or die("Failed to insert Data:" . $mysqli->error );
        
	$reg = mysqli_fetch_object( $mysqli->query("SELECT SEC_TO_TIME(session_time) as duration FROM realstatus WHERE id = ". $mysqli->insert_id) );
	$tot = mysqli_fetch_object( $mysqli->query("SELECT SEC_TO_TIME(sum(ifnull(session_time,0))) as total FROM realstatus WHERE sip_name ='{$event['peer']}' AND  datediff(ts,now()) = 0  GROUP BY sip_name" ) );
          echo " [ Calculated:  " . $reg->duration . ' Total today:'  . $tot->total . ' ] ';
	echo "\r\n";
	 
}

function NewChannelEvent($event,$PEER){ 
   GLOBAL $conf;
     echo "     New call  for $PEER  {$event['channel']} \r\n";
   }

function CallEndEvent($event, $PEER){
    GLOBAL $conf;
    GLOBAL $counters;
    //  print_r($event);
    echo " Call end for $PEER  {$event['channel']} \r\n";


}

function CallStartEvent($event, $PEER){
    GLOBAL $conf;
    GLOBAL $counters;
    //print_r($event);
    echo " Call Start: $PEER  {$event['channel']} \r\n";

}


function DialState($event){
    //print_r($event);
   
	$signals = array(
	       	      180 => 'RINGING',
		       183 => 'PROGRESS'
                        );

    $signals_txt = array ( 'RINGING' => 180,
                          'PROGRESS' => 183 );

    echo " DIAL STATUS: {$PEER}  {$event['dialstatus']} {$signals_txt[$event['dialstatus']]} for  {$event['destchannel']} \r\n";

}

To get this script running even after asterisk restart, on system boot, I’ve made initd script:
/etc/init.d/peerstatusd

#! /bin/sh
#/etc/init.d/$PROG
#
PROG=peerstatusd
SCRIPT='online.php'
LOG=/dev/null
#LOG=/var/log/peerstatus.log

# Some things that run always
touch /var/lock/

# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Starting $PROG "

      $(while true
        do
	 sleep 1 
	 echo "  Starting $PROG .." 
	 cd /var/www/html/ && while true; do php online.php; done >> $LOG 2>&1 || echo "Failed to start $PROG"
        done) &
   
     
    ;;
  stop)
    echo "Stopping script $SCRIPT"
    PID=`ps ax -o pid,cmd|grep "php ${SCRIPT}" | grep -v grep |awk '{print($1)}'`
    [ "${PID}s" != "s" ] && kill -9 $PID && echo  "Stopped ${SCRIPT} PID: ${PID}"
    killall -9 $PROG
    
    
    
    ;;
  *)
    echo "Usage: /etc/init.d/$PROG {start|stop}"
    exit 1
    ;;
esac

exit 0

enabled it by :
chkconfig peerstatusd on

logs and table records:

Mar 30 9:19:18 2020]  PeerStatus:  SIP/777  :  Registered   [ Calculated:  00:00:03 Total today:24:06:45 ] 
[Mar 30 9:19:21 2020]  PeerStatus:  SIP/777  :  Registered   [ Calculated:  00:00:03 Total today:24:06:48 ] 
[Mar 30 9:19:24 2020]  PeerStatus:  SIP/777  :  Registered   [ Calculated:  00:00:03 Total today:24:06:51 ] 
[Mar 30 9:19:27 2020]  PeerStatus:  SIP/777  :  Registered   [ Calculated:  00:00:03 Total today:24:06:54 ] 
[Mar 30 9:19:30 2020]  PeerStatus:  SIP/777  :  Registered   [ Calculated:  00:00:03 Total today:24:06:57 ] 
[Mar 30 9:19:31 2020]  PeerStatus:  SIP/501  :  Registered   [ Calculated:  00:00:18 Total today:24:07:07 ] 
[Mar 30 9:19:33 2020]  PeerStatus:  SIP/777  :  Registered   [ Calculated:  00:00:03 Total today:24:07:00 ] 
[Mar 30 9:19:36 2020]  PeerStatus:  SIP/777  :  Registered  Killed

it shows recent registry session, and total for today in the report.
If some one interested , will answer private messages with more details

1 Like

Thanks for your input!

Meanwhile, I tried this Python AMI client:

I managed to to solve the issue and implemented a check script as follows:

checkscript.txt (2.3 KB)