コード例 #1
0
 public static function hookProfiler()
 {
     if (!self::isProfilerRequested()) {
         return;
     }
     if (!self::isProfilerAvailable()) {
         return;
     }
     if (self::$profilerStarted) {
         return;
     }
     self::startProfiler();
     self::$profilerStarted = true;
 }
コード例 #2
0
 public static function hookProfiler()
 {
     if (empty($_REQUEST['__profile__'])) {
         return;
     }
     if (!self::isProfilerAvailable()) {
         return;
     }
     if (self::$profilerStarted) {
         return;
     }
     self::startProfiler();
     self::$profilerStarted = true;
 }
コード例 #3
0
 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();
 }
コード例 #4
0
 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();
 }
コード例 #5
0
 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();
 }
コード例 #7
0
 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);
 }
コード例 #8
0
ファイル: index.php プロジェクト: rudimk/phabricator
        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());
}
コード例 #9
0
 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);
 }
コード例 #10
0
 public function willShutdown()
 {
     if (isset($_REQUEST['__profile__']) && $_REQUEST['__profile__'] != 'all') {
         $this->xhprofID = DarkConsoleXHProfPluginAPI::stopProfiler();
     }
 }
コード例 #11
0
 /**
  * @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;
     }
 }
コード例 #12
0
 public function willShutdown()
 {
     $this->profileFilePHID = DarkConsoleXHProfPluginAPI::getProfileFilePHID();
 }
コード例 #13
0
 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();
 }
コード例 #14
0
 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();
 }
コード例 #15
0
ファイル: index.php プロジェクト: sethkontny/phabricator
            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);
}
コード例 #16
0
 public function willShutdown()
 {
     if (DarkConsoleXHProfPluginAPI::isProfilerRequested() && DarkConsoleXHProfPluginAPI::isProfilerRequested() !== 'all') {
         $this->xhprofID = DarkConsoleXHProfPluginAPI::stopProfiler();
     }
 }