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 = ''.
''.'| '.'time ago'.' | '.''.'time'.' | '.''.'class'.' | '.''.'message'.' | '.''.'code'.' | '.''.'file'.' | '.''.'line'.' | '.''.'ip'.' | '.''.'querytime'.' |
';
while($r = $res->next()){
//TODO make time conversion on database
if(\SYSTEM\system::isSystemDbInfoPG()){
- $result .= ''.'| '.self::time_elapsed_string(strtotime($r['time'])).' | '.''.$r['time'].' | '.''.$r['class'].' | '.''.$r['message'].' | '.''.$r['code'].' | '.''.$r['file'].' | '.''.$r['line'].' | '.''.$r['ip'].' | '.''.$r['querytime'].' | '.'
';
+ $result .= ''.'| '.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'].' | '.'
';
} else {
- $result .= ''.'| '.self::time_elapsed_string($r['time']).' | '.''.$r['time'].' | '.''.$r['class'].' | '.''.$r['message'].' | '.''.$r['code'].' | '.''.$r['file'].' | '.''.$r['line'].' | '.''.$r['ip'].' | '.''.$r['querytime'].' | '.'
';
+ $result .= ''.'| '.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 .= '
';
+ $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 = '
-
-
-
This action will delete all error messages from database.
- Are you sure?
-
-
-
-
-
-

-
-
-
-
-
-
-
-
-
-
-
';
-
-
- $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 @@
+
+
+
+
This action will delete all error messages from database.
Are you sure?
+
+
+
+
+
+
+

+
+
+ ${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();