Something went wrong. Try again.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
Something went wrong. Try again.
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201<?php
/** * @phutil-external-symbol function xhprof_enable * @phutil-external-symbol function xhprof_disable */final class DarkConsoleXHProfPluginAPI extends Phobject {
private static $profilerStarted; private static $profilerRunning; private static $profileFilePHID;
public static function isProfilerAvailable() { return extension_loaded('xhprof'); }
public static function getProfilerHeader() { return 'X-Phabricator-Profiler'; }
public static function isProfilerRequested() { if (!empty($_REQUEST['__profile__'])) { return $_REQUEST['__profile__']; }
$header = AphrontRequest::getHTTPHeader(self::getProfilerHeader()); if ($header) { return $header; }
return false; }
private static function shouldStartProfiler() { if (self::isProfilerRequested()) { return true; }
static $sample_request = null;
if ($sample_request === null) { if (PhabricatorEnv::getEnvConfig('debug.profile-rate')) { $rate = PhabricatorEnv::getEnvConfig('debug.profile-rate'); if (mt_rand(1, $rate) == 1) { $sample_request = true; } else { $sample_request = false; } } }
return $sample_request; }
public static function isProfilerStarted() { return self::$profilerStarted; }
private static function isProfilerRunning() { return self::$profilerRunning; }
public static function includeXHProfLib() { // TODO: this is incredibly stupid, but we may not have Phutil metamodule // stuff loaded yet so we can't just phutil_get_library_root() our way // to victory. $root = __FILE__; for ($ii = 0; $ii < 6; $ii++) { $root = dirname($root); }
require_once $root.'/externals/xhprof/xhprof_lib.php'; }
public static function saveProfilerSample(PhutilDeferredLog $access_log) { $file_phid = self::getProfileFilePHID(); if (!$file_phid) { return; }
if (self::isProfilerRequested()) { $sample_rate = 0; } else { $sample_rate = PhabricatorEnv::getEnvConfig('debug.profile-rate'); }
$profile_sample = id(new PhabricatorXHProfSample()) ->setFilePHID($file_phid) ->setSampleRate($sample_rate) ->setUsTotal($access_log->getData('T')) ->setHostname($access_log->getData('h')) ->setRequestPath($access_log->getData('U')) ->setController($access_log->getData('C')) ->setUserPHID($access_log->getData('P'));
AphrontWriteGuard::allowDangerousUnguardedWrites(true); $caught = null; try { $profile_sample->save(); } catch (Exception $ex) { $caught = $ex; } AphrontWriteGuard::allowDangerousUnguardedWrites(false);
if ($caught) { throw $caught; } }
public static function hookProfiler() { if (!self::shouldStartProfiler()) { return; }
if (!self::isProfilerAvailable()) { return; }
if (self::$profilerStarted) { return; }
self::startProfiler(); }
/** * @phutil-external-symbol class PhabricatorStartup */ private static function startProfiler() { PhabricatorStartup::beginStartupPhase('profiler.init');
self::includeXHProfLib(); xhprof_enable();
self::$profilerStarted = true; self::$profilerRunning = true; }
/** * @phutil-external-symbol class PhabricatorStartup */ public static function getProfileFilePHID() { if (!self::isProfilerRunning()) { return; }
PhabricatorStartup::beginStartupPhase('profiler.stop'); self::stopProfiler(); PhabricatorStartup::beginStartupPhase('profiler.done');
return self::$profileFilePHID; }
private static function stopProfiler() {
$data = xhprof_disable(); $data = @json_encode($data); self::$profilerRunning = false;
// Since these happen on GET we can't do guarded writes. These also // sometimes happen after we've disposed of the write guard; in this // case we need to disable the whole mechanism.
$use_scope = AphrontWriteGuard::isGuardActive(); if ($use_scope) { $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); } else { AphrontWriteGuard::allowDangerousUnguardedWrites(true); }
$caught = null; try { $file = call_user_func( array('PhabricatorFile', 'newFromFileData'), $data, array( 'mime-type' => 'application/xhprof', 'name' => 'profile.xhprof', )); } catch (Exception $ex) { $caught = $ex; }
if ($use_scope) { unset($unguarded); } else { AphrontWriteGuard::allowDangerousUnguardedWrites(false); }
if ($caught) { throw $caught; }
self::$profileFilePHID = $file->getPHID(); }
}