Author |
Message |
rovshan
Hangin' Around
Joined: Nov 26, 2005
Posts: 40
|
Posted:
Thu Apr 16, 2020 7:09 am |
|
hi,
My question concern this function in footer.php to show MySql requests concerning downloaded page:
Code:if ($loglevel == 3 || $loglevel == 4) {
if (is_admin($admin)) {
echo '<br /><br /><br /><br />'
, '<div id="queries" style="text-align:left; background-color:white;">'
, ' DB Queries: ' , $db->num_queries
, '<br /><br />';
foreach ($db->all_queries as $file => $queries) {
foreach ($queries as $num => $query) {
echo $num , ' - ' , $query , '<hr />';
}
}
echo '</div>';
}
}
|
The problem is that it returns in FILE info always the same info:
2 - LINE 488 - File: /var/www/somehost/...../httpdocs/mysite/db/mysqli.php
SELECT * FROM `nuke_config` LIMIT 0,1
QTIME:0.0009
--------
4 - LINE 488 - File: /var/www/somehost/...../httpdocs/mysite/db/mysqli.php
SELECT `ip_address` FROM `nuke_banned_ip` WHERE `ip_address`="10.01.00.*"
QTIME:0.0002
Cause of that, it is possible to find out in which file located this query!
As I understand above function linked to 2 functions below in mysqli file:
Code:
private function backtrace_log($query, $numrows, $failed = false, $query_id = false) {
$query_id = empty($query_id) ? $query_id : $this->query_result;
$this->backtrace();
if ($failed) {
$this->all_queries[$this->file][$this->num_queries] = '<span class="error thick">FAILED LINE ' . $this->line . ' - File: ' . $this->file . '</span><br />' . htmlspecialchars($query, ENT_QUOTES);
} else {
$this->all_queries[$this->file][$this->num_queries] = '<span class="thick">LINE ' . $this->line . ' - File: ' . $this->file . '</span><br />' . htmlspecialchars($query, ENT_QUOTES);
$this->all_queries[$this->file][$this->num_queries] .= '<br />QTIME:' . substr($this->qtime, 0, 5);
if (is_object($query_id)) $this->all_queries[$this->file][$this->num_queries] .= '[' . $numrows . ' results]';
}
}
/**
* Determines the filename and line of code where called and stores them.
*/
public function backtrace() {
$this->file = 'unknown';
$this->line = 0;
if (version_compare(phpversion(), '4.3.0', '>=')) {
$tmp = debug_backtrace();
for ($i=0; $i < count($tmp); ++$i) {
if (!preg_match('#[\\\/]{1}includes[\\\/]{1}db[\\\/]{1}[a-z_]+.php$#', $tmp[$i]['file'])) {
$this->file = $tmp[$i]['file'];
$this->line = $tmp[$i]['line'];
break;
}
}
}
}
|
As well as never get Error line like FAILED LINE, seems does not work.
How to fixe it? Any assistance you can provide would be greatly appreciated. |
|
|
|
|
neralex
Site Admin
Joined: Aug 22, 2007
Posts: 1774
|
Posted:
Thu Apr 16, 2020 1:46 pm |
|
rovshan, nice catch - crazy issue
Let us clarify how the loglevel-options should work:
Quote: | $loglevel - This controls the level of logging to the rnlogs/dblog file.
The default setting $loglevel = 0 will not generate any log entries.
$loglevel = 1 will generate entries only for SQL errors to the rnlogs/dblog file.
$loglevel = 2 will generate entries for all SQL queries (and errors) to the rnlogs/dblog file.
$loglevel = 3 does the same as $loglevel = 2 but the output of all queries is shown only as html-code in the footer but it is not written completely to the rnlogs/dblog file, only the errors are stored file-based.
$loglevel = 4 does the same as $loglevel = 2, but the output of all queries is shown as html-code in the footer and it is also written to the rnlogs/dblog file besides the errors. |
At first I added an incorrect sql-query somewhere in the code for testing the output of the different loglevel-options. I don't want add this incorrect query here to prevent irritations but I guess you are able to create something like this on your end.
After checking the code and the related files, it seems the boolean parameter: $failed of the function backtrace_log() inside the file: mysqli.php has got simply no functionality since the code was written. All function-calls are placed only in this file but before each call there is no check or no value-setting for this variable which can be passed into this function. Inside the function backtrace_log() is another call to the function backtrace(), which is already checking the passed query for the filename and the linenumber. The function-call of debug_backtrace() inside the function backtrace() returns an array and this array has an object, which returns vaules for the error-number (default: int 0) and the error-string (default: string '').
So I modified the function backtrace() to check if the object-value for the error-number (errno: int 0) has a value bigger than 0 and if yes, then it returns "true" like this:
php Code: public function backtrace() {
$this->file = 'unknown';
$this->line = 0;
$this->failed = false; # check-value
if (version_compare(phpversion(), '4.3.0', '>=')) {
$tmp = debug_backtrace();
for ($i=0; $i < count($tmp); ++$i) {
if (!preg_match('#[\\\/]{1}includes[\\\/]{1}db[\\\/]{1}[a-z_]+.php$#', $tmp[$i]['file'])) {
$this->file = $tmp[$i]['file'];
$this->line = $tmp[$i]['line'];
# error-check
if ($tmp[$i]['object']->errno > 0) {
$this->failed = true;
}
break;
}
}
}
}
|
After that I modified the function backtrace_log() to get the result-value of the added error-check like this:
php Code: private function backtrace_log($query, $numrows, $failed = false, $query_id = false) {
$query_id = empty($query_id) ? $query_id : $this->query_result;
$this->backtrace();
$failed = $this->failed; # get the check-value
if ($failed) {
$this->all_queries[$this->file][$this->num_queries] = '<span class="error thick">FAILED LINE ' . $this->line . ' - File: ' . $this->file . '</span><br />' . htmlspecialchars($query, ENT_QUOTES);
} else {
$this->all_queries[$this->file][$this->num_queries] = '<span class="thick">LINE ' . $this->line . ' - File: ' . $this->file . '</span><br />' . htmlspecialchars($query, ENT_QUOTES);
$this->all_queries[$this->file][$this->num_queries] .= '<br />QTIME: ' . substr($this->qtime, 0, 7); # increased substr from 5 to 7
if (is_object($query_id)) $this->all_queries[$this->file][$this->num_queries] .= '[' . $numrows . ' results]';
}
}
|
Note: On my tests many query-results for QTIME were often smaller than '0.0001', so I increased the substr() parameter: length from 5 to 7.
I'm not sure if this modification is the right way to fix it. It is atm not more as an 'walkaround' for the old logic behind the code but at the end the failed-query was marked with red color. So please test it and report your results. It may also affect other functions, resulting in errors that I overlooked in my tests so far. So please test it and post here your results.
For me it makes not really sense to use the boolean parameter: $failed of the function backtrace_log() but maybe kguske is able to tell something about the old logic. |
_________________ Github: RavenNuke |
|
|
|
rovshan
|
Posted:
Wed Apr 29, 2020 7:09 am |
|
Thank you very much neralex !
It seems your modifications catchs failed-query (red line) ! its ok.
But file path in LINE option rests the same for all queries:
LINE 488 - File: /var/www/somehost/...../httpdocs/mysite/db/mysqli.php
I use php 7.4 version. |
|
|
|
|
neralex
|
Posted:
Wed Apr 29, 2020 12:05 pm |
|
That is not an error or mistake because on this point the query is executed and if it is failed, then the backlog returns the error-message from this file. Which sql-errors are you getting? Maybe I can help you to identify the file, where the query is defined. |
|
|
|
|
rovshan
|
Posted:
Sun May 10, 2020 12:16 pm |
|
Thank you for your offer to help. I very appreciate.
I need this feature to catch errors in my own code. I did many modifications and tweaks + I have my own modules and sometimes it makes me crazy to find out form which file I get mysql error
And I need it mostly to control mysql execution time and find out slow queries to speed up my modules on my new server with php7.4
****************************************************************************************
Just remind to ravennuke users that there are usefull feature in rnconfig.php * SQL Logging to Text Log File.
By the way, small tweak which help to find mysql query location by url :
in mysqli.php after this line
Code:$logvar .= ' remote addr: ' . $_SERVER['REMOTE_ADDR'];
|
I added this code :
Code:$logvar .= ' uru: '.$_SERVER['SERVER_NAME'].' ' . $_SERVER['REQUEST_URI']. "\n";
$logvar .= ' string: ' . $_SERVER['QUERY_STRING']. "\n";
|
|
|
|
|
|
neralex
|
Posted:
Tue May 12, 2020 12:53 pm |
|
rovshan, thanks. I will check it in the days. |
|
|
|
|
|