public static function newInstance()
 {
     $instance = new MultimeterControl();
     // NOTE: We don't set the sample rate yet. This allows the multimeter to
     // be initialized and begin recording events, then make a decision about
     // whether the page will be sampled or not later on (once we've loaded
     // enough configuration).
     self::$instance = $instance;
     return self::getInstance();
 }
 public function processRequest()
 {
     $time_start = microtime(true);
     $request = $this->getRequest();
     $method = $this->method;
     $api_request = null;
     $method_implementation = null;
     $log = new PhabricatorConduitMethodCallLog();
     $log->setMethod($method);
     $metadata = array();
     $multimeter = MultimeterControl::getInstance();
     if ($multimeter) {
         $multimeter->setEventContext('api.' . $method);
     }
     try {
         list($metadata, $params) = $this->decodeConduitParams($request, $method);
         $call = new ConduitCall($method, $params);
         $method_implementation = $call->getMethodImplementation();
         $result = null;
         // TODO: The relationship between ConduitAPIRequest and ConduitCall is a
         // little odd here and could probably be improved. Specifically, the
         // APIRequest is a sub-object of the Call, which does not parallel the
         // role of AphrontRequest (which is an indepenent object).
         // In particular, the setUser() and getUser() existing independently on
         // the Call and APIRequest is very awkward.
         $api_request = $call->getAPIRequest();
         $allow_unguarded_writes = false;
         $auth_error = null;
         $conduit_username = '******';
         if ($call->shouldRequireAuthentication()) {
             $metadata['scope'] = $call->getRequiredScope();
             $auth_error = $this->authenticateUser($api_request, $metadata);
             // If we've explicitly authenticated the user here and either done
             // CSRF validation or are using a non-web authentication mechanism.
             $allow_unguarded_writes = true;
             if ($auth_error === null) {
                 $conduit_user = $api_request->getUser();
                 if ($conduit_user && $conduit_user->getPHID()) {
                     $conduit_username = $conduit_user->getUsername();
                 }
                 $call->setUser($api_request->getUser());
             }
         }
         $access_log = PhabricatorAccessLog::getLog();
         if ($access_log) {
             $access_log->setData(array('u' => $conduit_username, 'm' => $method));
         }
         if ($call->shouldAllowUnguardedWrites()) {
             $allow_unguarded_writes = true;
         }
         if ($auth_error === null) {
             if ($allow_unguarded_writes) {
                 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
             }
             try {
                 $result = $call->execute();
                 $error_code = null;
                 $error_info = null;
             } catch (ConduitException $ex) {
                 $result = null;
                 $error_code = $ex->getMessage();
                 if ($ex->getErrorDescription()) {
                     $error_info = $ex->getErrorDescription();
                 } else {
                     $error_info = $call->getErrorDescription($error_code);
                 }
             }
             if ($allow_unguarded_writes) {
                 unset($unguarded);
             }
         } else {
             list($error_code, $error_info) = $auth_error;
         }
     } catch (Exception $ex) {
         if (!$ex instanceof ConduitMethodNotFoundException) {
             phlog($ex);
         }
         $result = null;
         $error_code = $ex instanceof ConduitException ? 'ERR-CONDUIT-CALL' : 'ERR-CONDUIT-CORE';
         $error_info = $ex->getMessage();
     }
     $time_end = microtime(true);
     $connection_id = null;
     if (idx($metadata, 'connectionID')) {
         $connection_id = $metadata['connectionID'];
     } else {
         if ($method == 'conduit.connect' && $result) {
             $connection_id = idx($result, 'connectionID');
         }
     }
     $log->setCallerPHID(isset($conduit_user) ? $conduit_user->getPHID() : null)->setConnectionID($connection_id)->setError((string) $error_code)->setDuration(1000000 * ($time_end - $time_start));
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
     $log->save();
     unset($unguarded);
     $response = id(new ConduitAPIResponse())->setResult($result)->setErrorCode($error_code)->setErrorInfo($error_info);
     switch ($request->getStr('output')) {
         case 'human':
             return $this->buildHumanReadableResponse($method, $api_request, $response->toDictionary(), $method_implementation);
         case 'json':
         default:
             return id(new AphrontJSONResponse())->setAddJSONShield(false)->setContent($response->toDictionary());
     }
 }
 private function renderResource(CelerityResourceMap $map, $name)
 {
     $uri = $this->getURI($map, $name);
     $type = $map->getResourceTypeForName($name);
     $multimeter = MultimeterControl::getInstance();
     if ($multimeter) {
         $event_type = MultimeterEvent::TYPE_STATIC_RESOURCE;
         $multimeter->newEvent($event_type, 'rsrc.' . $name, 1);
     }
     switch ($type) {
         case 'css':
             return phutil_tag('link', array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => $uri));
         case 'js':
             return phutil_tag('script', array('type' => 'text/javascript', 'src' => $uri), '');
     }
     throw new Exception(pht('Unable to render resource "%s", which has unknown type "%s".', $name, $type));
 }
 public function processRequest(AphrontRequest $request, PhutilDeferredLog $access_log, AphrontHTTPSink $sink, MultimeterControl $multimeter)
 {
     $this->setRequest($request);
     list($controller, $uri_data) = $this->buildController();
     $controller_class = get_class($controller);
     $access_log->setData(array('C' => $controller_class));
     $multimeter->setEventContext('web.' . $controller_class);
     $request->setURIMap($uri_data);
     $controller->setRequest($request);
     // If execution throws an exception and then trying to render that
     // exception throws another exception, we want to show the original
     // exception, as it is likely the root cause of the rendering exception.
     $original_exception = null;
     try {
         $response = $controller->willBeginExecution();
         if ($request->getUser() && $request->getUser()->getPHID()) {
             $access_log->setData(array('u' => $request->getUser()->getUserName(), 'P' => $request->getUser()->getPHID()));
             $multimeter->setEventViewer('user.' . $request->getUser()->getPHID());
         }
         if (!$response) {
             $controller->willProcessRequest($uri_data);
             $response = $controller->handleRequest($request);
         }
     } catch (Exception $ex) {
         $original_exception = $ex;
         $response = $this->handleException($ex);
     }
     try {
         $response = $controller->didProcessRequest($response);
         $response = $this->willSendResponse($response, $controller);
         $response->setRequest($request);
         $unexpected_output = PhabricatorStartup::endOutputCapture();
         if ($unexpected_output) {
             $unexpected_output = pht("Unexpected output:\n\n%s", $unexpected_output);
             phlog($unexpected_output);
             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) {
         if ($original_exception) {
             throw $original_exception;
         }
         throw $ex;
     }
     return $response;
 }
 public function processRequest(AphrontRequest $request, PhutilDeferredLog $access_log, AphrontHTTPSink $sink, MultimeterControl $multimeter)
 {
     $this->setRequest($request);
     list($controller, $uri_data) = $this->buildController();
     $controller_class = get_class($controller);
     $access_log->setData(array('C' => $controller_class));
     $multimeter->setEventContext('web.' . $controller_class);
     $request->setController($controller);
     $request->setURIMap($uri_data);
     $controller->setRequest($request);
     // If execution throws an exception and then trying to render that
     // exception throws another exception, we want to show the original
     // exception, as it is likely the root cause of the rendering exception.
     $original_exception = null;
     try {
         $response = $controller->willBeginExecution();
         if ($request->getUser() && $request->getUser()->getPHID()) {
             $access_log->setData(array('u' => $request->getUser()->getUserName(), 'P' => $request->getUser()->getPHID()));
             $multimeter->setEventViewer('user.' . $request->getUser()->getPHID());
         }
         if (!$response) {
             $controller->willProcessRequest($uri_data);
             $response = $controller->handleRequest($request);
             $this->validateControllerResponse($controller, $response);
         }
     } catch (Exception $ex) {
         $original_exception = $ex;
         $response = $this->handleException($ex);
     }
     try {
         $response = $this->produceResponse($request, $response);
         $response = $controller->willSendResponse($response);
         $response->setRequest($request);
         self::writeResponse($sink, $response);
     } catch (Exception $ex) {
         if ($original_exception) {
             throw $original_exception;
         }
         throw $ex;
     }
     return $response;
 }