Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸ”¨ Better log highlighting #2369

Merged
merged 13 commits into from
Jan 15, 2024
4 changes: 2 additions & 2 deletions core/ajax/log.ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@
init('log'),
intval(init('position', 0)),
init('search'),
intval(init('colored', 0)),
init('numbered', true),
boolval(init('colored', 0)),
boolval(init('numbered', 1)),
intval(init('numberStart', 0))
)
);
Expand Down
15 changes: 10 additions & 5 deletions core/api/jeeApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,24 @@
echo "The page that you have requested could not be found.";
die();
}
/** @var user|null $_USER_GLOBAL */
global $_USER_GLOBAL;
$_USER_GLOBAL = null;
/** @var bool $_RESTRICTED */
global $_RESTRICTED;
$_RESTRICTED = false;
if (init('type') != '') {
try {
if (init('type') == 'ask') {
if (trim(init('token')) == '' || strlen(init('token')) < 64) {
throw new Exception(__('Token invalide', __FILE__));
throw new Exception(__('Commande inconnue ou Token invalide', __FILE__));
}
$cmd = cmd::byId(init('cmd_id'));
if (!is_object($cmd)) {
throw new Exception(__('Commande inconnue :', __FILE__) . ' ' . init('cmd_id'));
throw new Exception(__('Commande inconnue ou Token invalide', __FILE__));
}
if (trim($cmd->getCache('ask::token', config::genKey())) != init('token')) {
throw new Exception(__('Token invalide', __FILE__));
throw new Exception(__('Commande inconnue ou Token invalide', __FILE__));
}
if (!$cmd->askResponse(init('response'))) {
throw new Exception(__('Erreur response ask, temps Γ©coulΓ© ou rΓ©ponse invalide', __FILE__));
Expand Down Expand Up @@ -110,7 +112,7 @@
if ($type == 'interact') {
$query = init('query');
if (init('utf8', 0) == 1) {
$query = utf8_encode($query);
$query = mb_convert_encoding($query, 'UTF-8', 'ISO-8859-1');
}
$param = array();
if (init('emptyReply') != '') {
Expand Down Expand Up @@ -493,7 +495,7 @@
if (isset($params['key'])) {
$jsonrpc->makeSuccess(jeeObject::getGlobalSummary($params['key']));
}
$return = array();
/** @var array $def */
$def = config::byKey('object:summary');
foreach ($def as $key => &$value) {
$value['value'] = jeeObject::getGlobalSummary($key);
Expand Down Expand Up @@ -1328,6 +1330,9 @@
/* Mobile API */
if ($jsonrpc->getMethod() == 'getJson') {
log::add('api', 'debug', 'Demande du RDK to send with Json');
if (!is_object($_USER_GLOBAL)) {
throw new Exception(__('Utilisateur non dΓ©fini', __FILE__), -32500);
}
$registerDevice = $_USER_GLOBAL->getOptions('registerDevice', array());
if (!is_array($registerDevice)) {
$registerDevice = array();
Expand Down
3 changes: 2 additions & 1 deletion core/class/jeedom.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -614,8 +614,9 @@ public static function apiAccess($_apikey = '', $_plugin = 'core') {
}
$apikey = self::getApiKey($_plugin);
if (trim($apikey) != '' && $apikey === $_apikey) {
/** @var bool $_RESTRICTED */
global $_RESTRICTED;
$_RESTRICTED = config::byKey('api::' . $_plugin . '::restricted', 'core', 0);
$_RESTRICTED = config::byKey('api::' . $_plugin . '::restricted', 'core', false);
return true;
}
return false;
Expand Down
143 changes: 89 additions & 54 deletions core/class/log.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,14 @@ public static function removeAll() {
return true;
}

/*
/**
*
* @param string $_log
* @param int $_begin
* @param int $_nbLines
* @return boolean|array
*/
public static function get($_log = 'core', $_begin, $_nbLines) {
public static function get($_log, $_begin, $_nbLines) {
$path = (!file_exists($_log) || !is_file($_log)) ? self::getPathToLog($_log) : $_log;
if (!file_exists($path)) {
return false;
Expand All @@ -260,28 +260,33 @@ public static function get($_log = 'core', $_begin, $_nbLines) {
return $page;
}

/*
/**
* Get the log delta from $_position to the end of the file
* New position is stored in $_position when eof is reached
*
* @param string $_log Log filename (default 'core')
* @param int $_position Bytes representing position from the begining of the file (default 0)
* @param string $_search Text to find in log file (default '')
* @param int $_colored Should lines be colored (default 0) [0: no ; 1: global log colors ; 2: scenario colors]
* @param int $_colored Should lines be colored
* @param boolean $_numbered Should lines be numbered (default true)
* @param int $_numStart At what number should lines number start (default 0)
* @param int $_max Max number of returned lines (default 4000)
* @return array Array containing log to append to buffer and new position for next call
*/
public static function getDelta($_log = 'core', $_position = 0, $_search = '', $_colored = 0, $_numbered = true, $_numStart = 0, $_max = 4000) {
public static function getDelta($_log = 'core', $_position = 0, $_search = '', $_colored = false, $_numbered = true, $_numStart = 0, $_max = 4000) {
// Add path to file if needed
$filename = (file_exists($_log) && is_file($_log)) ? $_log : self::getPathToLog($_log);
// Check if log file exists and is readable
if (!file_exists($filename) || !$fp = fopen($filename, 'r'))
return array('position' => 0, 'line' => 0, 'logText' => '');
// Locate EOF
fseek($fp, 0, SEEK_END);
$_position = min($_position, ftell($fp));
// If log file has been truncated/altered (EOF is smaller than requested position)
// Then we restart from the start of the file
if (ftell($fp) < $_position) {
$_position = 0;
$_numStart = 0;
}
// Set file pointer at requested position or at EOF
fseek($fp, $_position);
// Iterate the file
Expand All @@ -305,66 +310,96 @@ public static function getDelta($_log = 'core', $_position = 0, $_search = '', $
$_position = ftell($fp);
fclose($fp);

// Display only the last jeedom.log.maxLines
// Display only the last maxLines
$logText = '';

$nbLogs = count($logs);
// If logs are TRUNCATED, then add a message
if (count($logs) > $_max) {
if ($nbLogs == 0) {
return array('position' => $_position, 'line' => $_numStart, 'logText' => $logText);
}
if ($nbLogs > $_max) {
// If logs must be TRUNCATED, then add a message
$logText .= "-------------------- TRUNCATED LOG --------------------\n";
$logs = array_slice($logs, -$_max, $_max);
}
// Merge all lignes
$logText .= implode('', $logs);
// Clear logs from HTML
$logText = secureXSS($logText);

// Apply color in logs
if ($_colored) {
// Highlight searched text first (when more than 3 chars)
if (strlen($_search) > 2) {
$srch = preg_quote($_search, '/');
$logText = preg_replace('/(' . $srch . ')/i', '<mark>$1</mark>', $logText);
}

$search = array(); $replace = array();
$search[] = '[DEBUG]'; $replace[] = '<span class="label label-xs label-success">&nbsp;D<&>EBUG&nbsp;</span>';
$search[] = '[INFO]'; $replace[] = '<span class="label label-xs label-info">&nbsp;I<&>NFO&nbsp;</span>';
$search[] = '[NOTICE]'; $replace[] = '<span class="label label-xs label-info">N<&>OTICE&nbsp;</span>';
$search[] = '[WARNING]'; $replace[] = '<span class="label label-xs label-warning">W<&>ARNING</span>';
$search[] = '[ERROR]'; $replace[] = '<span class="label label-xs label-danger">&nbsp;E<&>RROR&nbsp;</span>';
$search[] = '[CRITICAL]'; $replace[] = '<span class="label label-xs label-danger">&nbsp;C<&>RITI&nbsp;</span>';
$search[] = '[ALERT]'; $replace[] = '<span class="label label-xs label-danger">&nbsp;A<&>LERT&nbsp;</span>';
$search[] = '[EMERGENCY]'; $replace[] = '<span class="label label-xs label-danger">&nbsp;E<&>MERG&nbsp;</span>';

$search[] = '[ OK ]'; $replace[] = '<span class="label label-xs label-success">[&nbsp;&nbsp;O<&>K&nbsp;&nbsp;]</span>';
$search[] = '[ KO ]'; $replace[] = '<span class="label label-xs label-danger">[&nbsp;&nbsp;K<&>O&nbsp;&nbsp;]</span>';
$search[] = ' OK '; $replace[] = '<span class="label label-xs label-success"> O<&>K </span>';
$search[] = ' KO '; $replace[] = '<span class="label label-xs label-danger"> K<&>O </span>';
$search[] = 'ERROR'; $replace[] = '<span class="label label-xs label-danger">E<&>RROR</span>';
$search[] = 'PHP Notice:'; $replace[] = '<span class="warning">PHP N<&>otice:</span>';
$search[] = 'PHP Warning:'; $replace[] = '<span class="warning">PHP War<&>ning:</span>';
$search[] = 'PHP Stack trace:'; $replace[] = '<span class="danger">PHP S<&>tack trace:</span>';

$search[] = ':br:'; $replace[] = '<br>';
$search[] = ':bg-success:'; $replace[] = '<span class="label label-success">';
$search[] = ':bg-info:'; $replace[] = '<span class="label label-info">';
$search[] = ':bg-warning:'; $replace[] = '<span class="label label-warning">';
$search[] = ':bg-danger:'; $replace[] = '<span class="label label-danger">';
$search[] = ':/bg:'; $replace[] = '</span>';
$search[] = ':fg-success:'; $replace[] = '<span class="success">';
$search[] = ':fg-info:'; $replace[] = '<span class="info">';
$search[] = ':fg-warning:'; $replace[] = '<span class="warning">';
$search[] = ':fg-danger:'; $replace[] = '<span class="danger">';
$search[] = ':/fg:'; $replace[] = '</span>';
$search[] = ':b:'; $replace[] = '<b>';
$search[] = ':/b:'; $replace[] = '</b>';
$search[] = ':s:'; $replace[] = '<strong>';
$search[] = ':/s:'; $replace[] = '</strong>';
$search[] = ':i:'; $replace[] = '<i>';
$search[] = ':/i:'; $replace[] = '</i>';
$search[] = ':hide:'; $replace[] = '<!--';
$search[] = ':/hide:'; $replace[] = '-->';

// Apply color in system logs
if ($_colored == 1) {
$search = array(
'<',
'>',
'WARNING:',
'Erreur',
'OK',
'[DEBUG]',
'[INFO]',
'[NOTICE]',
'[WARNING]',
'[ERROR]',
'[CRITICAL]',
'[ALERT]',
'[EMERGENCY]',
'-------------------- TRUNCATED LOG --------------------'
);
$replace = array(
'&lt;',
'&gt;',
'<span class="warning">WARNING</span>',
'<span class="danger">Erreur</span>',
'<strong>OK</strong>',
'<span class="label label-xs label-success">DEBUG</span>',
'<span class="label label-xs label-info">INFO</span>',
'<span class="label label-xs label-info">NOTICE</span>',
'<span class="label label-xs label-warning">WARNING</span>',
'<span class="label label-xs label-danger">ERROR</span>',
'<span class="label label-xs label-danger">CRITI</span>',
'<span class="label label-xs label-danger">ALERT</span>',
'<span class="label label-xs label-danger">EMERG</span>',
'<span class="label label-xl label-danger">-------------------- TRUNCATED LOG --------------------</span>'
);
$logText = str_replace($search, $replace, $logText);
}
// Apply color in scenario logs
elseif ($_colored == 2) {
$search = array();
$replace = array();
foreach($GLOBALS['JEEDOM_SCLOG_TEXT'] as $item) {
$search[] = $item['txt'];
$replace[] = str_replace('::', $item['txt'], $item['replace']);
// Insert a marker into subject string to avoid replacing it multiple times
$subject = $item['txt'][0] . '<&>' . substr($item['txt'], 1);
$replace[] = str_replace('::', $subject, $item['replace']);
}

$replacables = array(
array('txt' => 'WARNING:', 'replace' => '<span class="warning">::</span>'),
array('txt' => 'Erreur', 'replace' => '<span class="danger">::</span>'),
array('txt' => 'OK', 'replace' => '<strong>::</strong>'),
array('txt' => 'Log :', 'replace' => '<span class="success">&nbsp;&nbsp;&nbsp;::</span>'),
array('txt' => '-------------------- TRUNCATED LOG --------------------', 'replace' => '<span class="label label-xl label-danger">::</span>')
);
foreach($replacables as $item) {
if (strlen($item['txt']) >= 2) {
$search[] = $item['txt'];
// Insert a marker into subject string to avoid replacing it multiple times
$subject = $item['txt'][0] . '<&>' . substr($item['txt'], 1);
$replace[] = str_replace('::', $subject, $item['replace']);
}
}
$search[] = ' Start : ';
$replace[] = '<strong> -- Start : </strong>';
$search[] = 'Log :';
$replace[] = '<span class="success">&ensp;&ensp;&ensp;Log :</span>';
// Replace everything in log
$logText = str_replace($search, $replace, $logText);
// Remove all inserted markers
$logText = str_replace('<&>', '', $logText);
}

// Return the lines to the end of the file, the new position and line number
Expand Down
4 changes: 2 additions & 2 deletions core/class/scenario.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -914,9 +914,9 @@ public function execute($_trigger = '', $_message = '') {
return;
}
if (count($this->getTags()) == 0) {
$this->setLog('Start : ' . trim($_message, "'") . '.');
$this->setLog($GLOBALS['JEEDOM_SCLOG_TEXT']['start']['txt'] . ' ' . trim($_message, "'") . '.');
} else {
$this->setLog('Start : ' . trim($_message, "'") . '. Tags : ' . json_encode($this->getTags()));
$this->setLog($GLOBALS['JEEDOM_SCLOG_TEXT']['start']['txt'] . ' ' . trim($_message, "'") . '. Tags : ' . json_encode($this->getTags()));
}
$this->setLastLaunch(date('Y-m-d H:i:s'));
$this->setState('in progress');
Expand Down
17 changes: 12 additions & 5 deletions core/class/scenarioExpression.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ public static function color_gradient($_from_color, $_to_color, $_min, $_max, $_
$RedOrigin = hexdec(substr($startcol, 1, 2));
$GrnOrigin = hexdec(substr($startcol, 3, 2));
$BluOrigin = hexdec(substr($startcol, 5, 2));
$RetVal = array();
if ($graduations >= 2) {
$GradientSizeRed = (hexdec(substr($endcol, 1, 2)) - $RedOrigin) / $graduations;
$GradientSizeGrn = (hexdec(substr($endcol, 3, 2)) - $GrnOrigin) / $graduations;
Expand Down Expand Up @@ -1064,10 +1065,10 @@ public static function time_diff($_date1, $_date2, $_format = 'd', $_rnd = 2) {
$dureeAbs %= 60;
$s = $dureeAbs;
$ret = '';
if ($j > 0) $ret .= "${j}j ";
if ($h > 0) $ret .= "${h}h ";
if ($m > 0) $ret .= "${m}min ";
if ($s > 0) $ret .= "${s}s";
if ($j > 0) $ret .= $j . 'j ';
if ($h > 0) $ret .= $h . 'h ';
if ($m > 0) $ret .= $m . 'min ';
if ($s > 0) $ret .= $s . 's';
return (trim($ret));
case 'df':
return round($duree / 86400, $_rnd); // en jours decimaux avec signe
Expand Down Expand Up @@ -1233,7 +1234,13 @@ public static function getRequestTags($_expression) {
return array_merge($return, $new);
}

public static function tag(&$_scenario = null, $_name, $_default = '') {
/**
* @param null|scenario $_scenario
* @param string $_name
* @param string $_default
* @return string
*/
public static function tag(&$_scenario, $_name, $_default = '') {
if ($_scenario == null) {
return $_default;
}
Expand Down
Loading
Loading