public static function hookProfiler() { if (!self::isProfilerRequested()) { return; } if (!self::isProfilerAvailable()) { return; } if (self::$profilerStarted) { return; } self::startProfiler(); self::$profilerStarted = true; }
public static function hookProfiler() { if (empty($_REQUEST['__profile__'])) { return; } if (!self::isProfilerAvailable()) { return; } if (self::$profilerStarted) { return; } self::startProfiler(); self::$profilerStarted = true; }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $data = $this->profileData; $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($data, $totals); unset($GLOBALS['display_calls']); $symbol = $this->symbol; $children = array(); $parents = array(); foreach ($this->profileData as $key => $counters) { if (strpos($key, '==>') !== false) { list($parent, $child) = explode('==>', $key, 2); } else { continue; } if ($parent == $symbol) { $children[$key] = $child; } else { if ($child == $symbol) { $parents[$key] = $parent; } } } $base_uri = $this->baseURI; $rows = array(); $rows[] = array('Metrics for this Call', '', '', ''); $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $symbol), phutil_escape_html($symbol)), $flat[$symbol]['ct'], $flat[$symbol]['wt'], '100%'); $rows[] = array('Parent Calls', '', '', ''); foreach ($parents as $key => $name) { $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $name), phutil_escape_html($name)), $data[$key]['ct'], $data[$key]['wt'], ''); } $rows[] = array('Child Calls', '', '', ''); $child_rows = array(); foreach ($children as $key => $name) { $child_rows[] = array($name, $data[$key]['ct'], $data[$key]['wt'], $data[$key]['wt'] / $flat[$symbol]['wt']); } $child_rows = isort($child_rows, 2); $child_rows = array_reverse($child_rows); $rows = array_merge($rows, $this->formatRows($child_rows)); $table = new AphrontTableView($rows); $table->setHeaders(array('Symbol', 'Count', 'Wall Time', '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n')); $panel = new AphrontPanelView(); $panel->setHeader('XHProf Profile'); $panel->appendChild($table); return $panel->render(); }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $data = $this->profileData; $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($data, $totals); unset($GLOBALS['display_calls']); $symbol = $this->symbol; $children = array(); $parents = array(); foreach ($this->profileData as $key => $counters) { if (strpos($key, '==>') !== false) { list($parent, $child) = explode('==>', $key, 2); } else { continue; } if ($parent == $symbol) { $children[$key] = $child; } else { if ($child == $symbol) { $parents[$key] = $parent; } } } $rows = array(); $rows[] = array(pht('Metrics for this Call'), '', '', ''); $rows[] = $this->formatRow(array($symbol, $flat[$symbol]['ct'], $flat[$symbol]['wt'], 1.0)); $rows[] = array(pht('Parent Calls'), '', '', ''); foreach ($parents as $key => $name) { $rows[] = $this->formatRow(array($name, $data[$key]['ct'], $data[$key]['wt'], '')); } $rows[] = array(pht('Child Calls'), '', '', ''); $child_rows = array(); foreach ($children as $key => $name) { $child_rows[] = array($name, $data[$key]['ct'], $data[$key]['wt'], $data[$key]['wt'] / $flat[$symbol]['wt']); } $child_rows = isort($child_rows, 2); $child_rows = array_reverse($child_rows); $rows = array_merge($rows, array_map(array($this, 'formatRow'), $child_rows)); $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Symbol'), pht('Count'), pht('Wall Time'), '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n')); $panel = new PHUIObjectBoxView(); $panel->setHeaderText(pht('XHProf Profile')); $panel->setTable($table); return $panel->render(); }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($this->profileData, $totals); unset($GLOBALS['display_calls']); $aggregated = array(); foreach ($flat as $call => $counters) { $parts = explode('@', $call, 2); $agg_call = reset($parts); if (empty($aggregated[$agg_call])) { $aggregated[$agg_call] = $counters; } else { foreach ($aggregated[$agg_call] as $key => $val) { if ($key != 'wt') { $aggregated[$agg_call][$key] += $counters[$key]; } } } } $flat = $aggregated; $flat = isort($flat, 'wt'); $flat = array_reverse($flat); $rows = array(); $rows[] = array(pht('Total'), number_format($totals['ct']), number_format($totals['wt']) . ' us', '100.0%', number_format($totals['wt']) . ' us', '100.0%'); if ($this->limit) { $flat = array_slice($flat, 0, $this->limit); } foreach ($flat as $call => $counters) { $rows[] = array($this->renderSymbolLink($call), number_format($counters['ct']), number_format($counters['wt']) . ' us', sprintf('%.1f%%', 100 * $counters['wt'] / $totals['wt']), number_format($counters['excl_wt']) . ' us', sprintf('%.1f%%', 100 * $counters['excl_wt'] / $totals['wt'])); } Javelin::initBehavior('phabricator-tooltips'); $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Symbol'), pht('Count'), javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Total wall time spent in this function and all of ' . 'its children (children are other functions it called ' . 'while executing).'), 'size' => 200)), pht('Wall Time (Inclusive)')), '%', javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Wall time spent in this function, excluding time ' . 'spent in children (children are other functions it ' . 'called while executing).'), 'size' => 200)), pht('Wall Time (Exclusive)')), '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n', 'n', 'n')); $panel = new PHUIObjectBoxView(); $header = id(new PHUIHeaderView())->setHeader(pht('XHProf Profile')); if ($this->file) { $button = id(new PHUIButtonView())->setHref($this->file->getBestURI())->setText(pht('Download %s Profile', '.xhprof'))->setTag('a'); $header->addActionLink($button); } $panel->setHeader($header); $panel->appendChild($table); return $panel->render(); }
public function render() { DarkConsoleXHProfPluginAPI::includeXHProfLib(); $GLOBALS['display_calls'] = true; $totals = array(); $flat = xhprof_compute_flat_info($this->profileData, $totals); unset($GLOBALS['display_calls']); $aggregated = array(); foreach ($flat as $call => $counters) { $parts = explode('@', $call, 2); $agg_call = reset($parts); if (empty($aggregated[$agg_call])) { $aggregated[$agg_call] = $counters; } else { foreach ($aggregated[$agg_call] as $key => $val) { if ($key != 'wt') { $aggregated[$agg_call][$key] += $counters[$key]; } } } } $flat = $aggregated; $flat = isort($flat, 'wt'); $flat = array_reverse($flat); $rows = array(); $rows[] = array('Total', number_format($totals['ct']), number_format($totals['wt']) . ' us', '100.0%', number_format($totals['wt']) . ' us', '100.0%'); if ($this->limit) { $flat = array_slice($flat, 0, $this->limit); } $base_uri = $this->baseURI; foreach ($flat as $call => $counters) { $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $call), phutil_escape_html($call)), number_format($counters['ct']), number_format($counters['wt']) . ' us', sprintf('%.1f%%', 100 * $counters['wt'] / $totals['wt']), number_format($counters['excl_wt']) . ' us', sprintf('%.1f%%', 100 * $counters['excl_wt'] / $totals['wt'])); } $table = new AphrontTableView($rows); $table->setHeaders(array('Symbol', 'Count', 'Incl Wall Time', '%', 'Excl Wall Time', '%')); $table->setColumnClasses(array('wide pri', 'n', 'n', 'n', 'n', 'n')); $panel = new AphrontPanelView(); $panel->setHeader('XHProf Profile'); $panel->appendChild($table); return $panel->render(); }
private function getConsoleConfig() { $user = $this->getRequest()->getUser(); $headers = array(); if (DarkConsoleXHProfPluginAPI::isProfilerStarted()) { $headers[DarkConsoleXHProfPluginAPI::getProfilerHeader()] = 'page'; } if (DarkConsoleServicesPlugin::isQueryAnalyzerRequested()) { $headers[DarkConsoleServicesPlugin::getQueryAnalyzerHeader()] = true; } if ($user) { $setting_tab = PhabricatorDarkConsoleTabSetting::SETTINGKEY; $setting_visible = PhabricatorDarkConsoleVisibleSetting::SETTINGKEY; $tab = $user->getUserSetting($setting_tab); $visible = $user->getUserSetting($setting_visible); } else { $tab = null; $visible = true; } return array('uri' => pht('Main Request'), 'selected' => $tab, 'visible' => $visible, 'headers' => $headers); }
phabricator_fatal('[Rendering Exception] ' . $ex->getMessage()); } $write_guard->dispose(); // TODO: Share the $sink->writeResponse() pathway here? $sink = new AphrontPHPHTTPSink(); $sink->writeHTTPStatus($response->getHTTPResponseCode()); $headers = $response->getCacheHeaders(); $headers = array_merge($headers, $response->getHeaders()); $sink->writeHeaders($headers); $sink->writeData($response_string); if ($access_log) { $access_log->setData(array('c' => $response->getHTTPResponseCode(), 'T' => (int) (1000000 * (microtime(true) - $__start__)))); $access_log->write(); } if (DarkConsoleXHProfPluginAPI::isProfilerRequested()) { $profile = DarkConsoleXHProfPluginAPI::stopProfiler(); $profile_sample = id(new PhabricatorXHProfSample())->setFilePHID($profile); if (empty($_REQUEST['__profile__'])) { $sample_rate = PhabricatorEnv::getEnvConfig('debug.profile-rate'); } else { $sample_rate = 0; } $profile_sample->setSampleRate($sample_rate); if ($access_log) { $profile_sample->setUsTotal($access_log->getData('T'))->setHostname($access_log->getData('h'))->setRequestPath($access_log->getData('U'))->setController($access_log->getData('C'))->setUserPHID($request->getUser()->getPHID()); } $profile_sample->save(); } } catch (Exception $ex) { phabricator_fatal("[Exception] " . $ex->getMessage()); }
private function getConsoleConfig() { $user = $this->getRequest()->getUser(); $headers = array(); if (DarkConsoleXHProfPluginAPI::isProfilerStarted()) { $headers[DarkConsoleXHProfPluginAPI::getProfilerHeader()] = 'page'; } if (DarkConsoleServicesPlugin::isQueryAnalyzerRequested()) { $headers[DarkConsoleServicesPlugin::getQueryAnalyzerHeader()] = true; } return array('uri' => pht('Main Request'), 'selected' => $user ? $user->getConsoleTab() : null, 'visible' => $user ? (int) $user->getConsoleVisible() : true, 'headers' => $headers); }
public function willShutdown() { if (isset($_REQUEST['__profile__']) && $_REQUEST['__profile__'] != 'all') { $this->xhprofID = DarkConsoleXHProfPluginAPI::stopProfiler(); } }
/** * @phutil-external-symbol class PhabricatorStartup */ public static function runHTTPRequest(AphrontHTTPSink $sink) { $multimeter = MultimeterControl::newInstance(); $multimeter->setEventContext('<http-init>'); $multimeter->setEventViewer('<none>'); // Build a no-op write guard for the setup phase. We'll replace this with a // real write guard later on, but we need to survive setup and build a // request object first. $write_guard = new AphrontWriteGuard('id'); PhabricatorEnv::initializeWebEnvironment(); $multimeter->setSampleRate(PhabricatorEnv::getEnvConfig('debug.sample-rate')); $debug_time_limit = PhabricatorEnv::getEnvConfig('debug.time-limit'); if ($debug_time_limit) { PhabricatorStartup::setDebugTimeLimit($debug_time_limit); } // This is the earliest we can get away with this, we need env config first. PhabricatorAccessLog::init(); $access_log = PhabricatorAccessLog::getLog(); PhabricatorStartup::setAccessLog($access_log); $access_log->setData(array('R' => AphrontRequest::getHTTPHeader('Referer', '-'), 'r' => idx($_SERVER, 'REMOTE_ADDR', '-'), 'M' => idx($_SERVER, 'REQUEST_METHOD', '-'))); DarkConsoleXHProfPluginAPI::hookProfiler(); DarkConsoleErrorLogPluginAPI::registerErrorHandler(); $response = PhabricatorSetupCheck::willProcessRequest(); if ($response) { PhabricatorStartup::endOutputCapture(); $sink->writeResponse($response); return; } $host = AphrontRequest::getHTTPHeader('Host'); $path = $_REQUEST['__path__']; switch ($host) { default: $config_key = 'aphront.default-application-configuration-class'; $application = PhabricatorEnv::newObjectFromConfig($config_key); break; } $application->setHost($host); $application->setPath($path); $application->willBuildRequest(); $request = $application->buildRequest(); // Now that we have a request, convert the write guard into one which // actually checks CSRF tokens. $write_guard->dispose(); $write_guard = new AphrontWriteGuard(array($request, 'validateCSRF')); // Build the server URI implied by the request headers. If an administrator // has not configured "phabricator.base-uri" yet, we'll use this to generate // links. $request_protocol = $request->isHTTPS() ? 'https' : 'http'; $request_base_uri = "{$request_protocol}://{$host}/"; PhabricatorEnv::setRequestBaseURI($request_base_uri); $access_log->setData(array('U' => (string) $request->getRequestURI()->getPath())); $processing_exception = null; try { $response = $application->processRequest($request, $access_log, $sink, $multimeter); $response_code = $response->getHTTPResponseCode(); } catch (Exception $ex) { $processing_exception = $ex; $response_code = 500; } $write_guard->dispose(); $access_log->setData(array('c' => $response_code, 'T' => PhabricatorStartup::getMicrosecondsSinceStart())); $multimeter->newEvent(MultimeterEvent::TYPE_REQUEST_TIME, $multimeter->getEventContext(), PhabricatorStartup::getMicrosecondsSinceStart()); $access_log->write(); $multimeter->saveEvents(); DarkConsoleXHProfPluginAPI::saveProfilerSample($access_log); // Add points to the rate limits for this request. if (isset($_SERVER['REMOTE_ADDR'])) { $user_ip = $_SERVER['REMOTE_ADDR']; // The base score for a request allows users to make 30 requests per // minute. $score = 1000 / 30; // If the user was logged in, let them make more requests. if ($request->getUser() && $request->getUser()->getPHID()) { $score = $score / 5; } PhabricatorStartup::addRateLimitScore($user_ip, $score); } if ($processing_exception) { throw $processing_exception; } }
public function willShutdown() { $this->profileFilePHID = DarkConsoleXHProfPluginAPI::getProfileFilePHID(); }
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(); }
protected function willRenderPage() { parent::willRenderPage(); if (!$this->getRequest()) { throw new Exception(pht('You must set the Request to render a PhabricatorStandardPageView.')); } $console = $this->getConsole(); require_celerity_resource('phabricator-core-css'); require_celerity_resource('phabricator-zindex-css'); require_celerity_resource('phui-button-css'); require_celerity_resource('phui-spacing-css'); require_celerity_resource('phui-form-css'); require_celerity_resource('sprite-gradient-css'); require_celerity_resource('phabricator-standard-page-view'); Javelin::initBehavior('workflow', array()); $request = $this->getRequest(); $user = null; if ($request) { $user = $request->getUser(); } if ($user) { $default_img_uri = celerity_get_resource_uri('rsrc/image/icon/fatcow/document_black.png'); $download_form = phabricator_form($user, array('action' => '#', 'method' => 'POST', 'class' => 'lightbox-download-form', 'sigil' => 'download'), phutil_tag('button', array(), pht('Download'))); Javelin::initBehavior('lightbox-attachments', array('defaultImageUri' => $default_img_uri, 'downloadForm' => $download_form)); } Javelin::initBehavior('aphront-form-disable-on-submit'); Javelin::initBehavior('toggle-class', array()); Javelin::initBehavior('konami', array()); Javelin::initBehavior('history-install'); Javelin::initBehavior('phabricator-gesture'); $current_token = null; if ($user) { $current_token = $user->getCSRFToken(); } Javelin::initBehavior('refresh-csrf', array('tokenName' => AphrontRequest::getCSRFTokenName(), 'header' => AphrontRequest::getCSRFHeaderName(), 'current' => $current_token)); Javelin::initBehavior('device'); if ($user->hasSession()) { $hisec = $user->getSession()->getHighSecurityUntil() - time(); if ($hisec > 0) { $remaining_time = phutil_format_relative_time($hisec); Javelin::initBehavior('high-security-warning', array('uri' => '/auth/session/downgrade/', 'message' => pht('Your session is in high security mode. When you ' . 'finish using it, click here to leave.', $remaining_time))); } } if ($console) { require_celerity_resource('aphront-dark-console-css'); $headers = array(); if (DarkConsoleXHProfPluginAPI::isProfilerStarted()) { $headers[DarkConsoleXHProfPluginAPI::getProfilerHeader()] = 'page'; } if (DarkConsoleServicesPlugin::isQueryAnalyzerRequested()) { $headers[DarkConsoleServicesPlugin::getQueryAnalyzerHeader()] = true; } Javelin::initBehavior('dark-console', array('uri' => pht('Main Request'), 'selected' => $user ? $user->getConsoleTab() : null, 'visible' => $user ? (int) $user->getConsoleVisible() : true, 'headers' => $headers)); // Change this to initBehavior when there is some behavior to initialize require_celerity_resource('javelin-behavior-error-log'); } if ($user) { $viewer = $user; } else { $viewer = new PhabricatorUser(); } $menu = id(new PhabricatorMainMenuView())->setUser($viewer); if ($this->getController()) { $menu->setController($this->getController()); } if ($this->getApplicationMenu()) { $menu->setApplicationMenu($this->getApplicationMenu()); } $this->menuContent = $menu->render(); }
if ($response instanceof AphrontWebpageResponse) { echo phutil_tag('div', array('style' => 'background: #eeddff;' . 'white-space: pre-wrap;' . 'z-index: 200000;' . 'position: relative;' . 'padding: 8px;' . 'font-family: monospace'), $unexpected_output); } } $sink->writeResponse($response); } catch (Exception $ex) { $write_guard->dispose(); $access_log->write(); if ($original_exception) { $ex = new PhutilAggregateException('Multiple exceptions during processing and rendering.', array($original_exception, $ex)); } PhabricatorStartup::didEncounterFatalException('Rendering Exception', $ex, $show_unexpected_traces); } $write_guard->dispose(); $access_log->setData(array('c' => $response->getHTTPResponseCode(), 'T' => PhabricatorStartup::getMicrosecondsSinceStart())); DarkConsoleXHProfPluginAPI::saveProfilerSample($access_log); // Add points to the rate limits for this request. if (isset($_SERVER['REMOTE_ADDR'])) { $user_ip = $_SERVER['REMOTE_ADDR']; // The base score for a request allows users to make 30 requests per // minute. $score = 1000 / 30; // If the user was logged in, let them make more requests. if ($request->getUser() && $request->getUser()->getPHID()) { $score = $score / 5; } PhabricatorStartup::addRateLimitScore($user_ip, $score); } } catch (Exception $ex) { PhabricatorStartup::didEncounterFatalException('Core Exception', $ex, $show_unexpected_traces); }
public function willShutdown() { if (DarkConsoleXHProfPluginAPI::isProfilerRequested() && DarkConsoleXHProfPluginAPI::isProfilerRequested() !== 'all') { $this->xhprofID = DarkConsoleXHProfPluginAPI::stopProfiler(); } }