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;