[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @phutil-external-symbol function xhprof_enable 5 * @phutil-external-symbol function xhprof_disable 6 */ 7 final class DarkConsoleXHProfPluginAPI { 8 9 private static $profilerStarted; 10 private static $profilerRunning; 11 private static $profileFilePHID; 12 13 public static function isProfilerAvailable() { 14 return extension_loaded('xhprof'); 15 } 16 17 public static function getProfilerHeader() { 18 return 'X-Phabricator-Profiler'; 19 } 20 21 public static function isProfilerRequested() { 22 if (!empty($_REQUEST['__profile__'])) { 23 return $_REQUEST['__profile__']; 24 } 25 26 $header = AphrontRequest::getHTTPHeader(self::getProfilerHeader()); 27 if ($header) { 28 return $header; 29 } 30 31 return false; 32 } 33 34 private static function shouldStartProfiler() { 35 if (self::isProfilerRequested()) { 36 return true; 37 } 38 39 static $sample_request = null; 40 41 if ($sample_request === null) { 42 if (PhabricatorEnv::getEnvConfig('debug.profile-rate')) { 43 $rate = PhabricatorEnv::getEnvConfig('debug.profile-rate'); 44 if (mt_rand(1, $rate) == 1) { 45 $sample_request = true; 46 } else { 47 $sample_request = false; 48 } 49 } 50 } 51 52 return $sample_request; 53 } 54 55 public static function isProfilerStarted() { 56 return self::$profilerStarted; 57 } 58 59 private static function isProfilerRunning() { 60 return self::$profilerRunning; 61 } 62 63 public static function includeXHProfLib() { 64 // TODO: this is incredibly stupid, but we may not have Phutil metamodule 65 // stuff loaded yet so we can't just phutil_get_library_root() our way 66 // to victory. 67 $root = __FILE__; 68 for ($ii = 0; $ii < 6; $ii++) { 69 $root = dirname($root); 70 } 71 72 require_once $root.'/externals/xhprof/xhprof_lib.php'; 73 } 74 75 76 public static function saveProfilerSample(PhutilDeferredLog $access_log) { 77 $file_phid = self::getProfileFilePHID(); 78 if (!$file_phid) { 79 return; 80 } 81 82 if (self::isProfilerRequested()) { 83 $sample_rate = 0; 84 } else { 85 $sample_rate = PhabricatorEnv::getEnvConfig('debug.profile-rate'); 86 } 87 88 $profile_sample = id(new PhabricatorXHProfSample()) 89 ->setFilePHID($file_phid) 90 ->setSampleRate($sample_rate) 91 ->setUsTotal($access_log->getData('T')) 92 ->setHostname($access_log->getData('h')) 93 ->setRequestPath($access_log->getData('U')) 94 ->setController($access_log->getData('C')) 95 ->setUserPHID($access_log->getData('P')); 96 97 AphrontWriteGuard::allowDangerousUnguardedWrites(true); 98 $caught = null; 99 try { 100 $profile_sample->save(); 101 } catch (Exception $ex) { 102 $caught = $ex; 103 } 104 AphrontWriteGuard::allowDangerousUnguardedWrites(false); 105 106 if ($caught) { 107 throw $caught; 108 } 109 } 110 111 public static function hookProfiler() { 112 if (!self::shouldStartProfiler()) { 113 return; 114 } 115 116 if (!self::isProfilerAvailable()) { 117 return; 118 } 119 120 if (self::$profilerStarted) { 121 return; 122 } 123 124 self::startProfiler(); 125 } 126 127 private static function startProfiler() { 128 self::includeXHProfLib(); 129 xhprof_enable(); 130 131 self::$profilerStarted = true; 132 self::$profilerRunning = true; 133 } 134 135 public static function getProfileFilePHID() { 136 self::stopProfiler(); 137 return self::$profileFilePHID; 138 } 139 140 private static function stopProfiler() { 141 if (!self::isProfilerRunning()) { 142 return; 143 } 144 145 $data = xhprof_disable(); 146 $data = @json_encode($data); 147 self::$profilerRunning = false; 148 149 // Since these happen on GET we can't do guarded writes. These also 150 // sometimes happen after we've disposed of the write guard; in this 151 // case we need to disable the whole mechanism. 152 153 $use_scope = AphrontWriteGuard::isGuardActive(); 154 if ($use_scope) { 155 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); 156 } else { 157 AphrontWriteGuard::allowDangerousUnguardedWrites(true); 158 } 159 160 $caught = null; 161 try { 162 $file = call_user_func( 163 array('PhabricatorFile', 'newFromFileData'), 164 $data, 165 array( 166 'mime-type' => 'application/xhprof', 167 'name' => 'profile.xhprof', 168 )); 169 } catch (Exception $ex) { 170 $caught = $ex; 171 } 172 173 if ($use_scope) { 174 unset($unguarded); 175 } else { 176 AphrontWriteGuard::allowDangerousUnguardedWrites(false); 177 } 178 179 if ($caught) { 180 throw $caught; 181 } 182 183 self::$profileFilePHID = $file->getPHID(); 184 } 185 186 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |