Recipes
Content Security Policy
If your site uses Content Security Policy (CSP), you'll need to add 'nonce-<value>'
and
'strict-dynamic'
to the script-src
directive for Tracy to function correctly. Some third-party plugins
might require additional directives. Nonce is not supported in the style-src
directive; if you use this directive,
you must add 'unsafe-inline'
, but this should be avoided in production mode.
Configuration example for Nette Framework:
http:
csp:
script-src: [nonce, strict-dynamic]
Example in pure PHP:
$nonce = base64_encode(random_bytes(20));
header("Content-Security-Policy: script-src 'nonce-$nonce' 'strict-dynamic';");
Faster Loading
Basic integration is straightforward. However, if you have slow-loading blocking scripts on your webpage, they can slow down
Tracy's loading. The solution is to place <?php Tracy\Debugger::renderLoader() ?>
in your template before any
scripts:
<!DOCTYPE html>
<html>
<head>
<title>...<title>
<?php Tracy\Debugger::renderLoader() ?>
<link rel="stylesheet" href="assets/style.css">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
Debugging AJAX Requests
Tracy automatically captures AJAX requests made using jQuery or the native fetch
API. These requests are displayed
as additional rows in the Tracy bar, enabling easy and convenient AJAX debugging.
If you do not want to capture AJAX requests automatically, you can disable this feature by setting the JavaScript variable:
window.TracyAutoRefresh = false;
For manual monitoring of specific AJAX requests, add the HTTP header X-Tracy-Ajax
with the value returned by
Tracy.getAjaxHeader()
. Here is an example of using it with the fetch
function:
fetch(url, {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-Tracy-Ajax': Tracy.getAjaxHeader(),
}
})
This approach allows for selective debugging of AJAX requests.
Data Storage
Tracy can display Tracy bar panels and Bluescreens for AJAX requests and redirects. Tracy creates its own sessions, stores data
in its own temporary files, and uses a tracy-session
cookie.
Tracy can also be configured to use a native PHP session, which must be started before enabling Tracy:
session_start();
Debugger::setSessionStorage(new Tracy\NativeSession);
Debugger::enable();
In case starting a session requires more complex initialization, you can start Tracy immediately (so that it can handle any
errors that occur) and then initialize the session handler. Finally, inform Tracy that the session is ready to be used using the
dispatch()
function:
Debugger::setSessionStorage(new Tracy\NativeSession);
Debugger::enable();
// followed by session initialization
// and start the session
session_start();
Debugger::dispatch();
The setSessionStorage()
function has existed since version 2.9; before that, Tracy always used the native PHP
session.
Custom Scrubber
A Scrubber is a filter that prevents sensitive data from leaking from dumps, such as passwords or credentials. The filter is
called for each item of the dumped array or object and returns true
if the value is sensitive. In this case,
*****
is printed instead of the value.
// prevents dumping values of keys and properties like `password`,
// `password_repeat`, `check_password`, `DATABASE_PASSWORD`, etc.
$scrubber = function(string $key, $value, ?string $class): bool
{
return preg_match('#password#i', $key) && $value !== null;
};
// use it for all dumps inside BlueScreen
Tracy\Debugger::getBlueScreen()->scrubber = $scrubber;
Custom Logger
We can create a custom logger that will log errors, uncaught exceptions, and will also be invoked by the
Tracy\Debugger::log()
method. The logger must implement the Tracy\ILogger interface.
use Tracy\ILogger;
class SlackLogger implements ILogger
{
public function log($value, $priority = ILogger::INFO)
{
// sends a request to Slack
}
}
And then we activate it:
Tracy\Debugger::setLogger(new SlackLogger);
If you are using the full Nette Framework, you can set it in the NEON configuration file:
services:
tracy.logger: SlackLogger
Monolog Integration
The Tracy package provides a PSR-3 adapter, allowing for integration of monolog/monolog.
$monolog = new Monolog\Logger('main-channel');
$monolog->pushHandler(new Monolog\Handler\StreamHandler($logFilePath, Monolog\Logger::DEBUG));
$tracyLogger = new Tracy\Bridges\Psr\PsrToTracyLoggerAdapter($monolog);
Debugger::setLogger($tracyLogger);
Debugger::enable();
Debugger::log('info'); // writes: [<TIMESTAMP>] main-channel.INFO: info [] []
Debugger::log('warning', Debugger::WARNING); // writes: [<TIMESTAMP>] main-channel.WARNING: warning [] []
nginx
If Tracy does not work on nginx, it is probably misconfigured. If there is something like:
try_files $uri $uri/ /index.php;
change it to:
try_files $uri $uri/ /index.php$is_args$args;