diff --git a/dbd/sql/pg/data/sai_api.sql b/dbd/sql/pg/data/sai_api.sql index bac7e78..275dbe0 100644 --- a/dbd/sql/pg/data/sai_api.sql +++ b/dbd/sql/pg/data/sai_api.sql @@ -17,4 +17,5 @@ INSERT INTO system.api ("ID", "group", type, "parentID", "parentValue", name, ve INSERT INTO system.api ("ID", "group", type, "parentID", "parentValue", name, verify) VALUES (35, 42, 2, 3, 'add', 'id', 'ALL'); INSERT INTO system.api ("ID", "group", type, "parentID", "parentValue", name, verify) VALUES (30, 42, 2, 3, 'edit', 'id', 'ALL'); INSERT INTO system.api ("ID", "group", type, "parentID", "parentValue", name, verify) VALUES (36, 42, 2, 3, 'add', 'category', 'INT'); +INSERT INTO system.api ("ID", "group", type, "parentID", "parentValue", name, verify) VALUES (40, 42, 3, 3, 'filter', 'filter', 'STRING'); INSERT INTO system.api ("ID", "group", type, "parentID", "parentValue", name, verify) VALUES (302, 42, 4, -1, NULL, '_lang', 'LANG'); diff --git a/log/log.php b/log/log.php index fa3d6dd..0f2f92c 100644 --- a/log/log.php +++ b/log/log.php @@ -18,13 +18,10 @@ class log { die("You registered an invalid Errorhandler!");} self::$handlers[] = $handler; - set_error_handler('\SYSTEM\LOG\log::__error_handler'); - set_exception_handler('\SYSTEM\LOG\log::__exception_handler'); - register_shutdown_function( '\SYSTEM\LOG\log::__shutdown_handler' ); - - ini_set('error_prepend_string', ''); - ini_set('error_append_string', ''); - ob_start('\SYSTEM\LOG\log::__fatal_error_handler'); + set_error_handler ('\SYSTEM\LOG\log::__error_handler'); + set_exception_handler ('\SYSTEM\LOG\log::__exception_handler'); + register_shutdown_function ( '\SYSTEM\LOG\log::__shutdown_handler' ); + ob_start ('\SYSTEM\LOG\log::__fatal_error_handler'); } private static function call_handlers(\Exception $E, $thrown = true){ @@ -47,15 +44,12 @@ class log { return self::call_handlers(new \SYSTEM\LOG\ShutdownException($error["message"], 1, $error["type"],$error["file"],$error["line"]) ,$thrown);} } - public static function __fatal_error_handler($bufferContent, $thrown = true){ - $errors = array(); - if ( preg_match('|.*|s', $bufferContent, $errors) ){ - $error = strip_tags($errors[0]); - $error = substr($error,1,strlen($error)-2); - $file = substr($error,strpos($error,' in ')+5,strpos($error,' on ')-5-strpos($error,' in ')); - $line = intval(substr($error,strpos($error,' line ')+6)); - $error = substr($error,0,strpos($error,' in ')); - return \SYSTEM\LOG\JsonResult::error(new \SYSTEM\LOG\ShutdownException($error,1,1,$file,$line));} + public static function __fatal_error_handler($bufferContent, $thrown = true){ + if( ($error = error_get_last()) !== NULL && !$error['type'] === E_DEPRECATED){ //seams like we cannot call anything but core stuff + $result = array('querytime' => 0, 'status' => false, 'result' => $error); + header('Access-Control-Allow-Origin: *');//allow cross domain calls + header('content-type: application/json'); + return json_encode($result);} return $bufferContent; } } diff --git a/sai/modules/saimod_sys_log/saimod_sys_log.js b/sai/modules/saimod_sys_log/saimod_sys_log.js index b1fbb83..78fb6a4 100644 --- a/sai/modules/saimod_sys_log/saimod_sys_log.js +++ b/sai/modules/saimod_sys_log/saimod_sys_log.js @@ -1,42 +1,149 @@ function init__SYSTEM_SAI_saimod_sys_log() { $('#truncate_table').click(function(){ - - $.ajax({ - type :'GET', - url : './?action=developer&sai_mod=.SYSTEM.SAI.saimod_sys_log&truncate=sys_log', - success : function(data) { - - if(data == 1){ - $('#info_box').html("deleting data..."); - $('#truncate_modal').modal('hide'); - $('#content-wrapper').load(SAI_ENDPOINT+'sai_mod=.SYSTEM.SAI.saimod_sys_log'); - }else{ - $('#info_box').html("You do not have the permission to truncate table!"); - } - - } + $.ajax({ type :'GET', + url : SAI_ENDPOINT+'sai_mod=.SYSTEM.SAI.saimod_sys_log&action=truncate', + success : function(data) { + if(data == 1){ + $('#info_box').html("deleting data..."); + $('#truncate_modal').modal('hide'); + $('#content-wrapper').load(SAI_ENDPOINT+'sai_mod=.SYSTEM.SAI.saimod_sys_log'); + }else{ + $('#info_box').html("You do not have the permission to truncate table!"); + } + } }); }); - $('#refresh_error_table').live("click", (function(){ - - $('img#loader').show(); - - $('#content-wrapper').load(SAI_ENDPOINT+'sai_mod=.SYSTEM.SAI.saimod_sys_log'); - - setTimeout("$('img#loader').hide()", 1300); - - })); + $('#refresh_error_table').live("click", (function(){ + do_filter("");})); - - $("#filter-error button").live("click", (function(){ - - $(this).parents().children().removeClass('active'); + $("#filter-error button").live("click", (function(){ + $('#filter-error button').each(function(){ + $(this).removeClass('active');}); $(this).addClass('active'); - - - $('#table-wrapper').load(SAI_ENDPOINT+'sai_mod=.SYSTEM.SAI.saimod_sys_log&filter_error='+$(this).attr('id')); + do_filter($(this).attr('filter'));})); + + $('#show_visualtization').live("click", (function(){ + drawVisualization(); })); -}; \ No newline at end of file + do_filter(""); +}; + +function drawVisualization() { + $('img#loader').show(); + $.getJSON(SAI_ENDPOINT+'sai_mod=.SYSTEM.SAI.saimod_sys_log&action=visualization',function(json){ + if(json.status != true){ + $('img#loader').hide(); + $('#visualization').hide(); + return; + } + json = json.result; + var data1 = new google.visualization.DataTable(); + data1.addColumn('date', 'day'); + data1.addColumn('number', 'count'); + //data.addColumn('string', 'from to'); + data1.addColumn('number', 'file_unique'); + data1.addColumn('number', 'ip_unique'); + data1.addColumn('number', 'text_unique'); + data1.addColumn('number', 'class_unique'); + + var data2 = new google.visualization.DataTable(); + data2.addColumn('date', 'day'); + data2.addColumn('number', 'count'); + data2.addColumn('number', 'querytime avg'); + data2.addColumn('number', 'querytime max'); + data2.addColumn('number', 'querytime min'); + + var data3 = new google.visualization.DataTable(); + data3.addColumn('date', 'day'); + data3.addColumn('number', 'count'); + data3.addColumn('number', 'class_info'); + data3.addColumn('number', 'class_deprecated'); + data3.addColumn('number', 'class_warning'); + data3.addColumn('number', 'class_error'); + data3.addColumn('number', 'class_apperror'); + + var data4 = new google.visualization.DataTable(); + data4.addColumn('date', 'day'); + data4.addColumn('number', 'count'); + data4.addColumn('number', 'class_system_log_info'); + data4.addColumn('number', 'class_system_log_deprecated'); + data4.addColumn('number', 'class_system_log_warning'); + data4.addColumn('number', 'class_system_log_error'); + data4.addColumn('number', 'class_system_log_errorexception'); + data4.addColumn('number', 'class_system_log_shutdownexception'); + + var data5 = new google.visualization.DataTable(); + data5.addColumn('date', 'day'); + data5.addColumn('number', 'count'); + data5.addColumn('number', 'class_exception'); + data5.addColumn('number', 'class_runtimeexception'); + data5.addColumn('number', 'class_errorexception'); + data5.addColumn('number', 'class_other'); + + $.each(json, function(key, value){ + data1.addRow([ new Date(value.day), + parseInt(value.count), + parseInt(value.file_unique), + parseInt(value.ip_unique), + parseInt(value.text_unique), + parseInt(value.class_unique)]); + data2.addRow([ new Date(value.day), + parseInt(value.count), + parseFloat(value.querytime_avg), + parseFloat(value.querytime_max), + parseFloat(value.querytime_min)]); + data3.addRow([ new Date(value.day), + parseInt(value.count), + parseInt(value.class_info)+0.5, + parseInt(value.class_deprecated)+0.5, + parseInt(value.class_warning)+0.5, + parseInt(value.class_error)+0.5, + parseInt(value.class_apperror)+0.5]); + data4.addRow([ new Date(value.day), + parseInt(value.count), + parseInt(value.class_system_log_info)+0.5, + parseInt(value.class_system_log_deprecated)+0.5, + parseInt(value.class_system_log_warning)+0.5, + parseInt(value.class_system_log_error)+0.5, + parseInt(value.class_system_log_errorexception)+0.5, + parseInt(value.class_system_log_shutdownexception)+0.5, + ]); + data5.addRow([ new Date(value.day), + parseInt(value.count), + parseInt(value.class_exception)+0.5, + parseInt(value.class_runtimeexception)+0.5, + parseInt(value.class_errorexception)+0.5, + parseInt(value.count)+0.5 - parseInt(value.class_info) - parseInt(value.class_deprecated) - parseInt(value.class_warning) - parseInt(value.class_error) - parseInt(value.class_apperror) - parseInt(value.class_system_log_info) - parseInt(value.class_system_log_deprecated) - parseInt(value.class_system_log_warning) - parseInt(value.class_system_log_error) - parseInt(value.class_system_log_errorexception) - parseInt(value.class_system_log_shutdownexception) - parseInt(value.class_exception) - parseInt(value.class_runtimeexception) - parseInt(value.class_errorexception)]); + }); + + + + // Create and draw the visualization. + var options = {title: 'Exception Occurrence', aggregationTarget: 'category', selectionMode: 'multiple', /*focusTarget: 'category',*/ chartArea:{left:100,top:40}, vAxis:{logScale: true}, interpolateNulls: false, width: "1400", height: "500"}; + new google.visualization.LineChart(document.getElementById('visualization1')).draw(data1, options); + var options = {title: 'Exception Querytime', /*focusTarget: 'category',*/ chartArea:{left:100,top:40}, vAxis:{logScale: true}, interpolateNulls: false, width: "1400", height: "500"}; + new google.visualization.LineChart(document.getElementById('visualization2')).draw(data2, options); + var options = {title: 'Exception Classes - basic', /*focusTarget: 'category',*/ chartArea:{left:100,top:40}, vAxis:{logScale: true}, interpolateNulls: false, width: "1400", height: "500"}; + new google.visualization.LineChart(document.getElementById('visualization3')).draw(data3, options); + var options = {title: 'Exception Classes - system', /*focusTarget: 'category',*/ chartArea:{left:100,top:40}, vAxis:{logScale: true}, interpolateNulls: false, width: "1400", height: "500"}; + new google.visualization.LineChart(document.getElementById('visualization4')).draw(data4, options); + var options = {title: 'Exception Classes - other', /*focusTarget: 'category',*/ chartArea:{left:100,top:40}, vAxis:{logScale: true}, interpolateNulls: false, width: "1400", height: "500"}; + new google.visualization.LineChart(document.getElementById('visualization5')).draw(data5, options); + + $('img#loader').hide(); + $('#table-wrapper').hide(); + $('#visualization').show(); + }); + +} + +function do_filter(filter){ + $('img#loader').show(); + $('#visualization').hide(); + $(this).parents().children().removeClass('active'); + $(this).addClass('active'); + $('#table-wrapper').load(SAI_ENDPOINT+'sai_mod=.SYSTEM.SAI.saimod_sys_log&action=filter&filter='+filter,function(){$('#table-wrapper').show(); $('img#loader').hide();}); +} \ No newline at end of file diff --git a/sai/modules/saimod_sys_log/saimod_sys_log.php b/sai/modules/saimod_sys_log/saimod_sys_log.php index 7395bca..95c7226 100644 --- a/sai/modules/saimod_sys_log/saimod_sys_log.php +++ b/sai/modules/saimod_sys_log/saimod_sys_log.php @@ -5,30 +5,64 @@ namespace SYSTEM\SAI; class saimod_sys_log extends \SYSTEM\SAI\SaiModule { - private static function truncate_syslog(){ + public static function sai_mod__SYSTEM_SAI_saimod_sys_log_action_truncate(){ if(\SYSTEM\SECURITY\Security::check(\SYSTEM\SECURITY\RIGHTS::SYS_SAI)){ $con = new \SYSTEM\DB\Connection(\SYSTEM\system::getSystemDBInfo()); $res = $con->query('TRUNCATE system.sys_log;'); return true; - }else{ - return false; - } + } + return false; + } + + public static function sai_mod__SYSTEM_SAI_saimod_sys_log_action_visualization(){ + $con = new \SYSTEM\DB\Connection(\SYSTEM\system::getSystemDBInfo()); + $res = $con->query('SELECT time::date as day, + min(time) as time_min, max(time) as time_max, + count(*) as count, + avg(querytime) as querytime_avg, + max(querytime) as querytime_max, + min(querytime) as querytime_min, + count(distinct file) as file_unique, + count(distinct ip) as ip_unique, + count(distinct message) as text_unique, + count(distinct class) as class_unique, + sum(case when class = \'INFO\' then 1 else 0 end) class_INFO, + sum(case when class = \'DEPRECATED\' then 1 else 0 end) class_DEPRECATED, + sum(case when class = \'WARNING\' then 1 else 0 end) class_WARNING, + sum(case when class = \'ERROR\' then 1 else 0 end) class_ERROR, + sum(case when class = \'AppError\' then 1 else 0 end) class_AppError, + sum(case when class = \'SYSTEM\LOG\INFO\' then 1 else 0 end) class_SYSTEM_LOG_INFO, + sum(case when class = \'SYSTEM\LOG\DEPRECATED\' then 1 else 0 end) class_SYSTEM_LOG_DEPRECATED, + sum(case when class = \'SYSTEM\LOG\WARNING\' then 1 else 0 end) class_SYSTEM_LOG_WARNING, + sum(case when class = \'SYSTEM\LOG\ERROR\' then 1 else 0 end) class_SYSTEM_LOG_ERROR, + sum(case when class = \'SYSTEM\LOG\ErrorException\' then 1 else 0 end) class_SYSTEM_LOG_ErrorException, + sum(case when class = \'SYSTEM\LOG\ShutdownException\' then 1 else 0 end) class_SYSTEM_LOG_ShutdownException, + sum(case when class = \'Exception\' then 1 else 0 end) class_Exception, + sum(case when class = \'RuntimeException\' then 1 else 0 end) class_RuntimeException, + sum(case when class = \'ErrorException\' then 1 else 0 end) class_ErrorException + from system.sys_log + group by day + order by day desc + limit 365;'); + $result = array(); + while($row = $res->next()){ + $result[] = $row;} + + return \SYSTEM\LOG\JsonResult::toString($result); } - - private static function build_table($filter){ - + public static function sai_mod__SYSTEM_SAI_saimod_sys_log_action_filter($filter = ""){ $con = new \SYSTEM\DB\Connection(\SYSTEM\system::getSystemDBInfo()); $res = null; - if($filter !== NULL && $filter !== 'all'){ + if($filter !== ""){ if(\SYSTEM\system::isSystemDbInfoPG()){ $res = $con->prepare( 'selectSysLogFilter', 'SELECT * FROM system.sys_log WHERE class ILIKE $1 ORDER BY time DESC LIMIT 100;', - array('%'.$filter.'%')); + array($filter)); } else { $res = $con->prepare( 'selectSysLogFilter', 'SELECT * FROM system_log WHERE class LIKE ? ORDER BY time DESC LIMIT 100;', - array('%'.$filter.'%')); + array($filter)); } } else { if(\SYSTEM\system::isSystemDbInfoPG()){ @@ -40,98 +74,58 @@ class saimod_sys_log extends \SYSTEM\SAI\SaiModule { $now = microtime(true); - $result = '
'. + $result = '
'. ''.''.''.''.''.''.''.''.''.''; while($r = $res->next()){ //TODO make time conversion on database if(\SYSTEM\system::isSystemDbInfoPG()){ - $result .= ''.''.''.''.''.''.''.''.''.''.''; + $result .= ''.''.''.''.''.''.''.''.''.''.''; } else { - $result .= ''.''.''.''.''.''.''.''.''.''.''; + $result .= ''.''.''.''.''.''.''.''.''.''.''; } } - $result .= '
'.'time ago'.''.'time'.''.'class'.''.'message'.''.'code'.''.'file'.''.'line'.''.'ip'.''.'querytime'.'
'.self::time_elapsed_string(strtotime($r['time'])).''.$r['time'].''.$r['class'].''.$r['message'].''.$r['code'].''.$r['file'].''.$r['line'].''.$r['ip'].''.$r['querytime'].'
'.self::time_elapsed_string(strtotime($r['time'])).''.$r['time'].''.$r['class'].''.substr($r['message'],0,255).''.$r['code'].''.$r['file'].''.$r['line'].''.$r['ip'].''.$r['querytime'].'
'.self::time_elapsed_string($r['time']).''.$r['time'].''.$r['class'].''.$r['message'].''.$r['code'].''.$r['file'].''.$r['line'].''.$r['ip'].''.$r['querytime'].'
'.self::time_elapsed_string($r['time']).''.$r['time'].''.$r['class'].''.substr($r['message'],0,255).''.$r['code'].''.$r['file'].''.$r['line'].''.$r['ip'].''.$r['querytime'].'
'; + $result .= ''; return $result; } - private static function time_elapsed_string($ptime) - { + private static function time_elapsed_string($ptime){ $etime = time() - $ptime; - - if ($etime < 1) - { - return '0 seconds'; - } + if ($etime < 1){ + return '0 seconds';} $a = array( 12 * 30 * 24 * 60 * 60 => 'year', 30 * 24 * 60 * 60 => 'month', 24 * 60 * 60 => 'day', 60 * 60 => 'hour', 60 => 'minute', - 1 => 'second' - ); + 1 => 'second'); - foreach ($a as $secs => $str) - { + foreach ($a as $secs => $str){ $d = $etime / $secs; - if ($d >= 1) - { + if ($d >= 1){ $r = round($d); - return $r . ' ' . $str . ($r > 1 ? 's' : '') . ' ago'; - } + return $r . ' ' . $str . ($r > 1 ? 's' : '') . ' ago';} } } - public static function sai_mod__SYSTEM_SAI_saimod_sys_log(){ + private static function generate_error_filters(){ + $con = new \SYSTEM\DB\Connection(\SYSTEM\system::getSystemDBInfo()); + $res = $con->query("SELECT class FROM system.sys_log GROUP BY class ORDER BY class;"); - - if( isset($_GET['truncate'])){ - return self::truncate_syslog(); - } - - if( isset($_GET['filter_error'])){ - return self::build_table($_GET['filter_error']); - }else{ - $filter = NULL; - } - - - $result = ' - - -
- - - - - - - -
- -

'; - - - $result .= self::build_table($filter); + $result = ""; + $i = 1; + while($row = $res->next()){ + $result .= ''.(($i++ % 6 == 0) ? '
' : '');} return $result; - + } + + public static function sai_mod__SYSTEM_SAI_saimod_sys_log(){ + $vars = array(); + $vars['error_filter'] = self::generate_error_filters(); + return \SYSTEM\PAGE\replace::replaceFile(\SYSTEM\SERVERPATH(new \SYSTEM\PSAI(),'modules/saimod_sys_log/saimod_sys_log.tpl'), $vars); } private static function tablerow_class($class){ diff --git a/sai/modules/saimod_sys_log/saimod_sys_log.tpl b/sai/modules/saimod_sys_log/saimod_sys_log.tpl new file mode 100644 index 0000000..74ed5fd --- /dev/null +++ b/sai/modules/saimod_sys_log/saimod_sys_log.tpl @@ -0,0 +1,34 @@ + + + + +
+ + ${error_filter} +

+
+ + +

+
+

+ \ No newline at end of file diff --git a/system/HEADER.php b/system/HEADER.php index 9a2206d..93ee28c 100644 --- a/system/HEADER.php +++ b/system/HEADER.php @@ -12,9 +12,8 @@ class HEADER { public static function JSON(){ self::checkHeader(); + header('Access-Control-Allow-Origin: *');//allow cross domain calls header('content-type: application/json'); - //header('Access-Control-Allow-Methods", "POST, GET, OPTIONS'); - //header('Access-Control-Allow-Headers *'); } public static function PNG(){ self::checkHeader();