dolibarr/htdocs/debugbar/class/DataCollector/DolQueryCollector.php

141 lines
3.4 KiB
PHP
Raw Permalink Normal View History

2019-03-16 15:27:14 +00:00
<?php
2023-01-14 14:57:12 +00:00
/* Copyright (C) 2023 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
add baseline exclude for phpstan (#31632) * add baseline exclude for phpstan * update * update * update * update * update * merge * restore one filter * delete old errors * fix * fix * fix * $moreforfilter can t be empty * fix * enable check * refresh baseline * add phpdoc * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * update phpstan baseline * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2024-11-04 22:53:20 +00:00
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
2023-01-14 14:57:12 +00:00
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/debugbar/class/DataCollector/DolQueryCollector.php
* \brief Class for debugbar collection
* \ingroup debugbar
*/
2019-03-16 15:27:14 +00:00
use DebugBar\DataCollector\AssetProvider;
use DebugBar\DataCollector\DataCollector;
use DebugBar\DataCollector\Renderable;
dol_include_once('/debugbar/class/TraceableDB.php');
/**
* DolQueryCollector class
*/
class DolQueryCollector extends DataCollector implements Renderable, AssetProvider
{
/**
* @var object Database handler
*/
protected $db;
/**
* Constructor
*/
public function __construct()
{
global $db;
2019-06-22 17:12:44 +00:00
// Replace $db handler with new handler override by TraceableDB
2019-03-16 15:27:14 +00:00
$db = new TraceableDB($db);
$this->db = $db;
}
/**
* Return collected data
*
* @return array<string,mixed> Array of collected data
2019-03-16 15:27:14 +00:00
*/
public function collect()
{
$queries = array();
$totalExecTime = 0;
$totalMemoryUsage = 0;
$totalFailed = 0;
foreach ($this->db->queries as $query) {
$queries[] = array(
'sql' => $query['sql'],
'duration' => $query['duration'],
'duration_str' => round((float) $query['duration'] * 1000, 2),
2019-03-16 15:27:14 +00:00
'memory' => $query['memory_usage'],
'is_success' => $query['is_success'],
'error_code' => $query['error_code'],
NEW debugbar: Add backtrace capture for database query failures (#36612) * debugbar: Add backtrace capture for database query failures Implements backtrace forwarding to capture and display backtraces when database queries fail, making it easier for developers to identify the source of database errors. Backtrace are captured in TraceableDB::endTracing() when queries fail using debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) and stored to be fowarded to the DolQueryCollector that will expose it to the debugbar integration. Because of that, the backtrace is now captured at the correct location, ie. when the query fails, rather than when the error is retrieved, ensuring it shows the actual application code that triggered the problematic query. This is particularly useful for debugging MySQL to PostgreSQL compatibility issues, module development and maintenance, and quickly identifying query origins during development. In particular, paired with the list and time profiling of each request, it will allow finding the location where queries are not properly optimized. Before this patch, it was possible to try and find snippets from the queries but because queries are generated at runtime, it was tedious and could lead to the wrong location. Related to #34050 * debugbar: Add SQL query backtrace Extends the debugbar SQL widget with backtrace display capabilities. To keep vendor files pristine, a custom widget (TracingSQLQueriesWidget) extends the vendor SQLQueriesWidget using DOM manipulation to inject Dolibarr-specific features after parent render completes. The widget intercepts the parent's data binding callback via wrapDataBinding() to enhance rendered queries with backtrace buttons. This patch pattern depends on php-debugbar internals but might break if the vendor API changes, without breaking the rendering done by php-debugbar. A tracing toggle icon in the status bar allows switching between tracing failed queries only (default, minimal overhead) and tracing all queries. The setting persists via cookie (debugbar_full_tracing) which the PHP backend reads to decide whether to capture backtraces. Custom styles in widgets.css is for the tracing state (eye/eye-slash icons) and so as to format the backtrace display within a frame and using monospace font. Closes #34050
2026-05-03 14:26:33 +00:00
'error_message' => $query['error_message'],
'backtrace' => isset($query['backtrace']) ? $query['backtrace'] : null
2019-03-16 15:27:14 +00:00
);
$totalExecTime += $query['duration'];
$totalMemoryUsage += $query['memory_usage'];
if (!$query['is_success']) {
2019-03-16 15:27:14 +00:00
$totalFailed += 1;
}
}
return array(
'nb_statements' => count($queries),
'nb_failed_statements' => $totalFailed,
'accumulated_duration' => $totalExecTime,
'memory_usage' => $totalMemoryUsage,
'statements' => $queries
);
}
/**
* Return collector name
*
2019-03-16 22:17:23 +00:00
* @return string Name
2019-03-16 15:27:14 +00:00
*/
public function getName()
{
return 'query';
}
/**
* Return widget settings
*
* @return array<string,array{icon?:string,widget?:string,tooltip?:string,map:string,default:int|string}> Array
2019-03-16 15:27:14 +00:00
*/
public function getWidgets()
{
global $langs;
$title = $langs->transnoentities('Database');
return array(
"$title" => array(
"icon" => "arrow-right",
"widget" => "PhpDebugBar.Widgets.SQLQueriesWidget",
"map" => "query",
"default" => "[]"
),
"$title:badge" => array(
"map" => "query.nb_statements",
"default" => 0
)
);
}
/**
* Return assets
*
* @return array<string,string> Array
2019-03-16 15:27:14 +00:00
*/
public function getAssets()
{
return array(
'css' => 'widgets/sqlqueries/widget.css',
'js' => 'widgets/sqlqueries/widget.js'
);
}
2019-03-16 22:17:23 +00:00
}