+
+ ';
+
+ // regular page
+ echo '
';
+ echo show_syslog($syslog_md5);
+ // syslog_md5 is used by javascript updateInfo() to determine if the syslog div contents have changed
+ echo '';
+ //echo "log goes here
";
+ echo '
';
+
+ echo '
';
+ echo show_aststats();
+ echo '
';
+
+ echo '
';
+ echo show_sysinfo();
+ echo '
';
+
+
+ echo '
';
+
+ echo '
';
+ echo show_sysstats();
+ echo '
';
+
+ echo '
';
+ echo show_procinfo();
+ echo '
';
+
+ echo '
';
+ echo '
'; // #sysinfo-right, #dashboard
+ echo '
 
';
+
+ if($dashboard_debug && $error->ErrorsExist()) {
+ $fh = fopen($amp_conf['ASTLOGDIR']."/dashboard-error.log","a");
+ fwrite($fh, $error->ErrorsAsText());
+ fclose($fh);
+ }
+
+} else {
+ // Handle AJAX updates
+
+ switch ($info) {
+ case "sysstats":
+ echo show_sysstats();
+ break;
+ case "aststats":
+ echo show_aststats();
+ break;
+ case "procinfo":
+ echo show_procinfo();
+ break;
+ case 'sysinfo':
+ echo show_sysinfo();
+ break;
+ case 'syslog':
+ echo show_syslog($syslog_md5);
+ // syslog_md5 is used by javascript updateInfo() to determine if the syslog div contents have changed
+ echo '';
+ break;
+ case 'syslog_ack':
+ do_syslog_ack();
+ break;
+ case 'syslog_delete':
+ do_syslog_delete();
+ break;
+
+ case 'info':
+ $json = new Services_JSON();
+ header("Content-type: application/json");
+ echo $json->encode(
+ array(
+ 'procinfo'=>show_procinfo(),
+ 'sysinfo'=>show_sysinfo(),
+ 'syslog'=>show_syslog($syslog_md5),
+ 'syslog_md5'=>$syslog_md5,
+ )
+ );
+ break;
+ case 'stats':
+ $json = new Services_JSON();
+ header("Content-type: application/json");
+ echo $json->encode(
+ array(
+ 'sysstats'=>show_sysstats(),
+ 'aststats'=>show_aststats(),
+ )
+ );
+ break;
+ case 'all':
+ $json = new Services_JSON();
+ header("Content-type: application/json");
+ echo $json->encode(
+ array(
+ 'sysstats'=>show_sysstats(),
+ 'aststats'=>show_aststats(),
+ 'procinfo'=>show_procinfo(),
+ 'sysinfo'=>show_sysinfo(),
+ 'syslog'=>show_syslog(),
+ )
+ );
+ break;
+ }
+}
+
+?>
Index: freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.procinfo.php
===================================================================
--- freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.procinfo.php (revision 8935)
+++ freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.procinfo.php (revision 8935)
@@ -0,0 +1,45 @@
+distro = $distro;
+ }
+
+ function check_port($port, $server = "localhost") {
+ $timeout = 5;
+ if ($sock = @fsockopen($server, $port, $errno, $errstr, $timeout)) {
+ fclose($sock);
+ return true;
+ }
+ return false;
+ }
+
+ function check_fop_server() {
+ global $amp_conf;
+ $fop_settings = parse_ini_file($amp_conf['FOPWEBROOT'].'/op_server.cfg');
+ if (is_array($fop_settings)) {
+ $listen_port = isset($fop_settings['listen_port']) && trim($fop_settings['listen_port']) != ''?$fop_settings['listen_port']:4445;
+ } else {
+ $listen_port = 4445;
+ }
+
+ return $this->check_port($listen_port);
+ }
+
+ function check_mysql($hoststr) {
+ $host = 'localhost';
+ $port = '3306';
+ if (preg_match('/^([^:]+)(:(\d+))?$/',$hoststr,$matches)) {
+ // matches[1] = host, [3] = port
+ $host = $matches[1];
+ if (!empty($matches[3])) {
+ $port = $matches[3];
+ }
+ }
+ return $this->check_port($port, $host);
+ }
+}
+
+?>
Index: freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.error.inc.php
===================================================================
--- freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.error.inc.php (revision 7633)
+++ freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.error.inc.php (revision 7633)
@@ -0,0 +1,143 @@
+arrErrorList[$this->errors]['command'] = $strCommand;
+ $this->arrErrorList[$this->errors]['message'] = $strMessage;
+ $this->arrErrorList[$this->errors]['line'] = $intLine;
+ $this->arrErrorList[$this->errors]['file'] = basename( $strFile );
+ $this->errors++;
+ }
+
+ /**
+ *
+ * ErrorsAsHTML()
+ *
+ * @param -
+ *
+ * @return string string which contains a HTML table which can be used to echo out the errors
+ *
+ **/
+ function ErrorsAsHTML() {
+ $strHTMLString = "";
+ $strWARNString = "";
+ $strHTMLhead = "
\n"
+ . " \n"
+ . " | File | \n"
+ . " Line | \n"
+ . " Command | \n"
+ . " Message | \n"
+ . "
\n";
+ $strHTMLfoot = "
";
+
+ if( $this->errors > 0 ) {
+ foreach( $this->arrErrorList as $arrLine ) {
+ if( $arrLine['command'] == "WARN" ) {
+ $strWARNString .= "
WARNING: " . htmlspecialchars( $arrLine['message'] ) . "\n";
+ } else {
+ $strHTMLString .= "
\n"
+ . " | " . htmlspecialchars( $arrLine['file'] ) . " | \n"
+ . " " . $arrLine['line'] . " | \n"
+ . " " . htmlspecialchars( $arrLine['command'] ) . " | \n"
+ . " " . htmlspecialchars( $arrLine['message'] ) . " | \n"
+ . "
\n";
+ }
+ }
+ }
+
+ if( !empty( $strHTMLString ) ) {
+ $strHTMLString = $strWARNString . $strHTMLhead . $strHTMLString . $strHTMLfoot;
+ } else {
+ $strHTMLString = $strWARNString;
+ }
+
+ return $strHTMLString;
+ }
+
+ /**
+ *
+ * ErrorsAsText()
+ *
+ * @param -
+ *
+ * @return string string which contains a table which can be used to echo out the errors
+ *
+ **/
+ function ErrorsAsText() {
+ $strHTMLString = "";
+ $strWARNString = "";
+ $strHTMLhead = sprintf("%24s %6s %40s %s\n","File", "Line", "Command", "Message");
+ $strHTMLfoot = "\n";
+
+ if( $this->errors > 0 ) {
+ foreach( $this->arrErrorList as $arrLine ) {
+ if( $arrLine['command'] == "WARN" ) {
+ $strWARNString .= "WARNING: " . $arrLine['message'] . "\n";
+ } else {
+ $strHTMLString .= sprintf("%24s %6s %40s %s\n",$arrLine['file'], $arrLine['line'], $arrLine['command'], $arrLine['message'] );
+ }
+ }
+ }
+
+ if( !empty( $strHTMLString ) ) {
+ $strHTMLString = $strWARNString . $strHTMLhead . $strHTMLString . $strHTMLfoot;
+ } else {
+ $strHTMLString = $strWARNString;
+ }
+
+ return $strHTMLString;
+ }
+
+ /**
+ *
+ * ErrorsExist()
+ *
+ * @param -
+ *
+ * @return true there are errors logged
+ * false no errors logged
+ *
+ **/
+ function ErrorsExist() {
+ if( $this->errors > 0 ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+}
+?>
Index: freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.astinfo.php
===================================================================
--- freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.astinfo.php (revision 8096)
+++ freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/class.astinfo.php (revision 8096)
@@ -0,0 +1,278 @@
+astman =& $astman;
+ $arr = engine_getinfo();
+ $this->version = $arr['version'];
+ }
+
+ function get_channel_totals() {
+ if (!$this->astman) {
+ return array(
+ 'external_calls'=>0,
+ 'internal_calls'=>0,
+ 'total_calls'=>0,
+ 'total_channels'=>0,
+ );
+ }
+ if (version_compare($this->version, "1.6", "ge")) {
+ $response = $this->astman->send_request('Command',array('Command'=>"core show channels"));
+ } else {
+ $response = $this->astman->send_request('Command',array('Command'=>"show channels"));
+ }
+ $astout = explode("\n",$response['data']);
+
+ $external_calls = 0;
+ $internal_calls = 0;
+ $total_calls = 0;
+ $total_channels = 0;
+
+ foreach ($astout as $line) {
+ if (preg_match('/s@macro-dialout/', $line)) {
+ $external_calls++;
+ } else if (preg_match('/s@macro-dial:/', $line)) {
+ $internal_calls++;
+ } else if (preg_match('/^(\d+) active channel/i', $line, $matches)) {
+ $total_channels = $matches[1];
+ } else if (preg_match('/^(\d+) active call/i', $line, $matches)) {
+ $total_calls = $matches[1];
+ }
+ }
+ return array(
+ 'external_calls'=>$external_calls,
+ 'internal_calls'=>$internal_calls,
+ 'total_calls'=>$total_calls,
+ 'total_channels'=>$total_channels,
+ );
+ }
+
+ function get_connections($devices = false) {
+ if (!$devices) {
+ $devices = array();
+ }
+
+ $return = array(
+ 'sip_users_online' => 0,
+ 'sip_users_offline' => 0,
+ 'sip_users_total' => 0,
+ 'sip_trunks_online' => 0,
+ 'sip_trunks_offline' => 0,
+ 'sip_trunks_total' => 0,
+ 'sip_registrations_online' => 0,
+ 'sip_registrations_offline' => 0,
+ 'sip_registrations_total' => 0,
+
+
+ 'iax2_users_online' => 0,
+ 'iax2_users_offline' => 0,
+ 'iax2_users_total' => 0,
+ 'iax2_trunks_online' => 0,
+ 'iax2_trunks_offline' => 0,
+ 'iax2_trunks_total' => 0,
+ 'iax2_registrations_online' => 0,
+ 'iax2_registrations_offline' => 0,
+ 'iax2_registrations_total' => 0,
+
+ //totals
+ 'users_online' => 0,
+ 'users_offline' => 0,
+ 'users_total' => 0,
+ 'trunks_online' => 0,
+ 'trunks_offline' => 0,
+ 'trunks_total' => 0,
+ 'registrations_online' => 0,
+ 'registrations_offline' => 0,
+ 'registrations_total' => 0,
+ );
+
+ if (!$this->astman) {
+ return $return;
+ }
+
+ $response = $this->astman->send_request('Command',array('Command'=>"sip show peers"));
+ $astout = explode("\n",$response['data']);
+ foreach ($astout as $line) {
+ if (preg_match('/^(([a-z0-9\-_]+)(\/([a-z0-9\-_]+))?)\s+(\([a-z]+\)|\d{1,3}(\.\d{1,3}){3})/i', $line, $matches)) {
+ //matches: [2] = name, [4] = username, [5] = host, [6] = part of ip (if IP)
+
+ // have an IP address listed, so its online
+ $online = !empty($matches[6]);
+
+ if (!isset($devices[$matches[2]])) {
+ // this is a trunk
+ //TODO match trunk tech as well?
+ $return['sip_trunks_'.($online?'online':'offline')]++;
+ } else {
+ $return['sip_users_'.($online?'online':'offline')]++;
+ }
+ }
+ }
+
+
+ $response = $this->astman->send_request('Command',array('Command'=>"sip show registry"));
+ $astout = explode("\n",$response['data']);
+ $pos = false;
+ foreach ($astout as $line) {
+ if (trim($line) != '') {
+ if ($pos===false) {
+ // find the position of "State" in the first line
+ $pos = strpos($line,"State");
+ } else {
+ // subsequent lines, check if it says "Registered" at that position
+ if (substr($line,$pos,10) == "Registered") {
+ $return['sip_registrations_online']++;
+ } elseif (strlen($line) > $pos) {
+ $return['sip_registrations_offline']++;
+ }
+ }
+ }
+ }
+
+ $response = $this->astman->send_request('Command',array('Command'=>"iax2 show peers"));
+ $astout = explode("\n",$response['data']);
+ foreach ($astout as $line) {
+ if (preg_match('/^(([a-z0-9\-_]+)(\/([a-z0-9\-_]+))?)\s+(\([a-z]+\)|\d{1,3}(\.\d{1,3}){3})/i', $line, $matches)) {
+ //matches: [2] = name, [4] = username, [5] = host, [6] = part of ip (if IP)
+
+ // have an IP address listed, so its online
+ $online = !empty($matches[6]);
+
+ if (!isset($devices[$matches[2]])) {
+ // this is a trunk
+ //TODO match trunk tech as well?
+ $return['iax2_trunks_'.($online?'online':'offline')]++;
+ } else {
+ $return['iax2_users_'.($online?'online':'offline')]++;
+ }
+ }
+ }
+
+
+ $response = $this->astman->send_request('Command',array('Command'=>"iax2 show registry"));
+ $astout = explode("\n",$response['data']);
+ $pos = false;
+ foreach ($astout as $line) {
+ if (trim($line) != '') {
+ if ($pos===false) {
+ // find the position of "State" in the first line
+ $pos = strpos($line,"State");
+ } else {
+ // subsequent lines, check if it syas "Registered" at that position
+ if (substr($line,$pos,10) == "Registered") {
+ $return['iax2_registrations_online']++;
+ } elseif (strlen($line) > $pos) {
+ $return['iax2_registrations_offline']++;
+ }
+ }
+ }
+ }
+
+ $return['sip_users_total'] = $return['sip_users_online'] + $return['sip_users_offline'];
+ $return['sip_trunks_total'] = $return['sip_trunks_online'] + $return['sip_trunks_offline'];
+ $return['sip_registrations_total'] = $return['sip_registrations_online'] + $return['sip_registrations_offline'];
+
+ $return['iax2_users_total'] = $return['iax2_users_online'] + $return['iax2_users_offline'];
+ $return['iax2_trunks_total'] = $return['iax2_trunks_online'] + $return['iax2_trunks_offline'];
+ $return['iax2_registrations_total'] = $return['iax2_registrations_online'] + $return['iax2_registrations_offline'];
+
+ $return['users_online'] = $return['sip_users_online'] + $return['iax2_users_online'];
+ $return['users_offline'] = $return['sip_users_offline'] + $return['iax2_users_offline'];
+ $return['users_total'] = $return['users_online'] + $return['users_offline'];
+
+ $return['trunks_online'] = $return['sip_trunks_online'] + $return['iax2_trunks_online'];
+ $return['trunks_offline'] = $return['sip_trunks_offline'] + $return['iax2_trunks_offline'];
+ $return['trunks_total'] = $return['trunks_online'] + $return['trunks_offline'];
+
+ $return['registrations_online'] = $return['sip_registrations_online'] + $return['iax2_registrations_online'];
+ $return['registrations_offline'] = $return['sip_registrations_offline'] + $return['iax2_registrations_offline'];
+ $return['registrations_total'] = $return['registrations_online'] + $return['registrations_offline'];
+
+ return $return;
+ }
+
+ function get_uptime() {
+ /*
+ System uptime: 1 week, 4 days, 22 hours, 29 minutes, 21 seconds
+ Last reload: 1 week, 1 day, 6 hours, 14 minutes, 49 seconds
+ */
+ $output = array(
+ 'system' => '',
+ 'reload' => '',
+ );
+
+ if (!$this->astman) {
+ return $output;
+ }
+
+ if (version_compare($this->version, "1.6", "ge")) {
+ $response = $this->astman->send_request('Command',array('Command'=>"core show uptime"));
+ } else {
+ $response = $this->astman->send_request('Command',array('Command'=>"show uptime"));
+ }
+ $astout = explode("\n",$response['data']);
+
+
+ // Only translate and do the preg_replace if in another language, since it is a somewhat expensive operation
+ //
+ if (!isset($_COOKIE['lang']) || $_COOKIE['lang'] == "en_US") {
+ $translate = false;
+ } else {
+ $translate = true;
+ $units = array(
+ '/\bseconds\b/', '/\bsecond\b/',
+ '/\bminutes\b/', '/\bminute\b/',
+ '/\bhours\b/', '/\bhour\b/',
+ '/\bdays\b/', '/\bday\b/',
+ '/\bweeks\b/', '/\bweek\b/',
+ '/\byears\b/', '/\byear\b/',
+ );
+ $tunits = array(
+ _('seconds'), _('second'),
+ _('minutes'), _('minute'),
+ _('hours'), _('hour'),
+ _('days'), _('day'),
+ _('weeks'), _('week'),
+ _('years'), _('year'),
+ );
+ }
+ foreach ($astout as $line) {
+ if (preg_match('/^System uptime: (.*)$/i',$line,$matches)) {
+ $output["system"] = preg_replace('/,\s+(\d+ seconds?)?\s*$/', '', $matches[1]);
+ if ($translate) {
+ $output["system"] = preg_replace($units,$tunits,$output["system"]);
+ }
+ } else if (preg_match('/^Last reload: (.*)$/i',$line,$matches)) {
+ $output["reload"] = preg_replace('/,\s+(\d+ seconds?)?\s*$/', '', $matches[1]);
+ if ($translate) {
+ $output["reload"] = preg_replace($units,$tunits,$output["reload"]);
+ }
+ }
+ }
+
+ return $output;
+ }
+
+ function check_asterisk() {
+ if (!$this->astman) {
+ return false;
+ }
+ if (version_compare($this->version, "1.6", "ge")) {
+ $response = $this->astman->send_request('Command',array('Command'=>"core show version"));
+ } else {
+ $response = $this->astman->send_request('Command',array('Command'=>"show version"));
+ }
+ $astout = explode("\n",$response['data']);
+
+ if (!preg_match('/^Asterisk /i', $astout[1])) {
+ return false;
+ } else {
+ return $astout[1];
+ }
+ }
+}
+
+?>
Index: freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/dashboard.css
===================================================================
--- freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/dashboard.css (revision 10204)
+++ freepbx/tags/2.9.0alpha1/amp_conf/htdocs/admin/modules/dashboard/dashboard.css (revision 10204)
@@ -0,0 +1,152 @@
+#dashboard {
+ position:relative;
+}
+
+/* two columns, sizes of each category box */
+#sysinfo-left, #sysinfo-left .infobox {
+ width:400px;
+ float: left;
+}
+
+#sysinfo-right {
+ float: left;
+ width:200px;
+ padding-left: 30px;
+}
+#sysinfo-right .infobox {
+ width:200px;
+}
+#sysinfo-bot{
+ clear:both;
+}
+/* main container for each category of items */
+.infobox {
+ border:1px solid black;
+ padding:0 5px 5px 5px;
+ margin-bottom:1em;
+ background:white;
+ background-image:url(images/dashboard-sysinfo.png);
+ background-repeat:repeat-x;
+ color: #333;
+}
+
+#procinfo.infobox {
+ margin-bottom: 0px;
+}
+
+/* headings */
+.infobox h4 , .infobox h3 {
+ margin-bottom:8px;
+ margin-top:5px;
+}
+.infobox h3 {
+ color: white;
+}
+
+/* main container for each item */
+.databox {
+ position:relative;
+ border:1px solid #ccc;
+ font-size:9pt;
+ margin-top:4px;
+}
+/* height of main container and actual bar graph */
+.databox , .graphbox .bargraph {
+ height:12pt;
+}
+/* positioning of data title */
+.databox .dataname {
+ position:absolute;
+ top:1pt;
+ left:2px;
+}
+/* positioning of the value shown in boxes */
+.databox .datavalue {
+ position:absolute;
+ top:1pt;
+ right:2px;
+}
+
+/* graph colors */
+.databox .graphok {
+ background:#0d0;
+}
+.databox .graphwarn {
+ background:yellow;
+}
+.databox .grapherror {
+ background:red;
+}
+
+/* modifier for graph* classes, when inside a "status box" */
+.statusbox .datavalue {
+ width:60px;
+ text-align:center;
+ font-weight:Bold;
+}
+
+#sysinfo table th {
+ text-align:right;
+}
+
+
+#syslog ul {
+ list-style-type:none;
+ padding-left:0;
+ margin:0;
+}
+#syslog ul li {
+ position:relative;
+ margin-bottom:0.2em;
+ border-bottom:1px dashed #ccc;
+ margin-top:1px;
+ color:#333;
+}
+#syslog ul li>div {
+ padding-left:2px;
+}
+#syslog ul li .notification_buttons {
+ position:absolute;
+ right:0;
+ top:0;
+}
+#syslog ul li .notification_buttons a {
+ cursor:pointer;
+}
+#syslog ul li.notify_critical>div, #syslog ul li.notify_security>div {
+ /*background:#F7181C;*/
+ background:#f6921d;
+}
+#syslog ul li.notify_critical h4, #syslog ul li.notify_security h4 {
+ color:white;
+}
+/*
+
+/*
+#syslog .notify_ignore_btn {
+ background-image:url(images/notify_delete.png);
+ background-repeat:no-repeat;
+ width:16px;
+ height:16px;
+ display:inline;
+}
+*/
+
+#syslog h4 {
+ margin:0;
+ font-weight:normal;
+}
+#syslog h4 span {
+ cursor:pointer;
+}
+/* hide details by default */
+#syslog div.syslog_detail {
+ display:none;
+ font-size:75%;
+ height:7em;
+ overflow:auto;
+}
+#syslog div.syslog_detail span {
+ font-style:italic;
+}
+