Tarifler
Content Security Policy
Siteniz Content Security Policy (CSP) kullanıyorsa, Tracy'nin düzgün çalışması için script-src
yönergesine 'nonce-<value>' ve 'strict-dynamic' eklemeniz gerekir. Bazı üçüncü taraf
eklentileri ek yönergeler isteyebilir. style-src yönergesinde nonce desteklenmez; bu yönergeyi kullanıyorsanız
'unsafe-inline' eklemeniz gerekir, ama üretim kipinde bundan kaçınılmalıdır.
Nette Framework için yapılandırma örneği:
http:
csp:
script-src: [nonce, strict-dynamic]
Saf PHP'de örnek:
$nonce = base64_encode(random_bytes(20));
header("Content-Security-Policy: script-src 'nonce-$nonce' 'strict-dynamic';");
Daha Hızlı Yükleme
Temel tümleştirme dolaysızdır. Ancak web sayfanızda yavaş yüklenen engelleyici betikler varsa, bunlar Tracy'nin
yüklenmesini yavaşlatabilir. Çözüm, şablonunuzda <?php Tracy\Debugger::renderLoader() ?> satırını tüm
betiklerden önce koymaktır:
<!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>
Çıktının Kaynağını Bulma
Hiç Cannot modify header information – headers already sent hatasıyla karşılaştınız mı? Bu hata, kodunuz bir HTTP header ayarlamadan ya da bir oturum başlatmadan önce tarayıcıya bir şey gönderildiğinde (başıboş bir boşluk, boş bir satır ya da bir dosyanın başındaki BOM) ortaya çıkar. Suçluyu bulmak yorucudur.
Tracy\OutputDebugger yardım eder. Onu programınızın en başında etkinleştirin:
Tracy\OutputDebugger::enable();
Tüm çıktıyı izler ve sayfanın sonunda, çıktının gönderildiği her yerin listesini; dosya, satır ve düzenleyicinizde açan bir bağlantıyla birlikte yazdırır. Bir dosyanın başındaki bayt sırası işareti (BOM) de vurgulanır; çünkü sorunun yaygın ve görünmez bir nedenidir.
AJAX İsteklerinde Hata Ayıklama
Tracy, jQuery ya da yerleşik fetch API'siyle yapılan AJAX isteklerini otomatik olarak yakalar. Bu istekler Tracy
çubuğunda ek satırlar olarak görüntülenir ve AJAX'ta kolay ve rahat hata ayıklamayı sağlar.
AJAX isteklerinin otomatik yakalanmasını istemiyorsanız, bu özelliği şu JavaScript değişkenini ayarlayarak kapatabilirsiniz:
window.TracyAutoRefresh = false;
Belirli AJAX isteklerini elle izlemek için, Tracy.getAjaxHeader() metodunun döndürdüğü değere sahip
X-Tracy-Ajax HTTP header'ını ekleyin. fetch fonksiyonuyla kullanımına bir örnek:
fetch(url, {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-Tracy-Ajax': Tracy.getAjaxHeader(),
}
})
Bu yaklaşım, AJAX isteklerinde seçmeli hata ayıklamaya olanak tanır.
Veri Saklama
Tracy, AJAX istekleri ve yönlendirmeler için Tracy çubuğu panellerini ve Bluescreen'leri gösterebilir. Tracy kendi
oturumlarını oluşturur, verileri kendi geçici dosyalarında saklar ve bir tracy-session çerezi kullanır.
Tracy, PHP'nin yerleşik oturumunu kullanacak şekilde de yapılandırılabilir; bu oturum, Tracy etkinleştirilmeden önce başlatılmalıdır:
session_start();
Debugger::setSessionStorage(new Tracy\NativeSession);
Debugger::enable();
Oturum başlatmak daha karmaşık bir hazırlık gerektiriyorsa, Tracy'yi hemen başlatabilir (böylece oluşan hataları ele
alabilir), sonra oturum işleyicisini hazırlayabilirsiniz. En sonunda dispatch() fonksiyonuyla Tracy'ye oturumun
kullanıma hazır olduğunu bildirin:
Debugger::setSessionStorage(new Tracy\NativeSession);
Debugger::enable();
// ardından oturum hazırlığı
// ve oturumu başlat
session_start();
Debugger::dispatch();
setSessionStorage() fonksiyonu 2.9 sürümünden beri vardır; ondan önce Tracy her zaman PHP'nin yerleşik
oturumunu kullanıyordu.
Özel Scrubber
Scrubber, parola ya da kimlik bilgileri gibi hassas verilerin dökümlerden sızmasını önleyen bir filtredir. Filtre,
dökülen dizinin ya da nesnenin her öğesi için çağrılır ve değer hassassa true döndürür. Bu durumda
değer yerine ***** yazdırılır.
// `password`, `password_repeat`, `check_password`, `DATABASE_PASSWORD` gibi
// anahtarların ve özelliklerin değerlerinin dökülmesini önler
$scrubber = function(string $key, $value, ?string $class): bool
{
return preg_match('#password#i', $key) && $value !== null;
};
// BlueScreen içindeki tüm dökümlerde kullan
Tracy\Debugger::getBlueScreen()->scrubber = $scrubber;
Özel Logger
Hataları ve yakalanmamış istisnaları günlükleyecek, ayrıca Tracy\Debugger::log() metodunca çağrılacak
özel bir logger yazabiliriz. Logger, Tracy\ILogger
arayüzünü uygulamalıdır.
use Tracy\ILogger;
class SlackLogger implements ILogger
{
public function log($value, $priority = ILogger::INFO)
{
// Slack'e bir istek gönderir
}
}
Ve sonra onu etkinleştiririz:
Tracy\Debugger::setLogger(new SlackLogger);
Nette Framework'ün tamamını kullanıyorsanız, onu NEON yapılandırma dosyasında ayarlayabilirsiniz:
services:
tracy.logger: SlackLogger
Monolog Tümleştirmesi
Tracy paketi bir PSR-3 adaptörü sunar; bu da monolog/monolog tümleştirmesine olanak tanır.
$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'); // yazar: [<TIMESTAMP>] main-channel.INFO: info [] []
Debugger::log('warning', Debugger::WARNING); // yazar: [<TIMESTAMP>] main-channel.WARNING: warning [] []
Sentry Tümleştirmesi
Tracy'nin kendi günlüklemesini korurken hataları Sentry gibi bir servise iletebilirsiniz. Fikir, özgün logger'ı sarmalamaktır: yeni logger mesajı Sentry'ye aktarır ve sonra bir öncekine devreder; böylece dosya günlükleri ve e-posta bildirimleri çalışmayı sürdürür.
use Sentry\Severity;
use Tracy\Debugger;
use Tracy\ILogger;
class SentryLogger implements ILogger
{
private ILogger $originalLogger;
public function __construct(string $dsn)
{
$this->originalLogger = Debugger::getLogger();
\Sentry\init(['dsn' => $dsn]);
}
public function log(mixed $value, string $level = self::INFO)
{
// Sentry'ye gönder
if ($severity = $this->getSeverity($level)) {
$value instanceof \Throwable
? \Sentry\captureException($value)
: \Sentry\captureMessage((string) $value, $severity);
}
// Tracy'nin özgün günlüklemesini koru (dosyalar, e-posta)
return $this->originalLogger->log($value, $level);
}
private function getSeverity(string $level): ?Severity
{
return match ($level) {
ILogger::DEBUG => Severity::debug(),
ILogger::INFO => Severity::info(),
ILogger::WARNING => Severity::warning(),
ILogger::ERROR, ILogger::EXCEPTION => Severity::error(),
ILogger::CRITICAL => Severity::fatal(),
default => null,
};
}
}
Onu, başka herhangi bir özel logger gibi etkinleştirin:
Debugger::setLogger(new SentryLogger('https://public@sentry.example.com/1'));
Bir Nette uygulamasında ise onu tracy.logger servisi olarak kaydedin:
services:
tracy.logger: SentryLogger('https://public@sentry.example.com/1')
nginx
Tracy nginx'te çalışmıyorsa, büyük olasılıkla yanlış yapılandırılmıştır. Şuna benzer bir şey varsa:
try_files $uri $uri/ /index.php;
onu şununla değiştirin:
try_files $uri $uri/ /index.php$is_args$args;