1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 01:08:50 +02:00

Add "request time" event and viewer and context data to Multimeter

Summary: Ref T6930. Only notable thing here is that I prevented non-admins from slicing down by viewing user, since it feels a little creepy to go see what pages you looked at, even though we only show which controllers you invoked. However, it feels important enough to be able to see users destorying the server with crazy requests to let admins see this data.

Test Plan: {F389718}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T6930

Differential Revision: https://secure.phabricator.com/D12630
This commit is contained in:
epriestley 2015-05-01 13:20:30 -07:00
parent 1448073314
commit 59416a13e7
4 changed files with 77 additions and 11 deletions

View file

@ -125,7 +125,11 @@ abstract class AphrontApplicationConfiguration {
$processing_exception = null; $processing_exception = null;
try { try {
$response = $application->processRequest($request, $access_log, $sink); $response = $application->processRequest(
$request,
$access_log,
$sink,
$multimeter);
$response_code = $response->getHTTPResponseCode(); $response_code = $response->getHTTPResponseCode();
} catch (Exception $ex) { } catch (Exception $ex) {
$processing_exception = $ex; $processing_exception = $ex;
@ -140,6 +144,11 @@ abstract class AphrontApplicationConfiguration {
'T' => PhabricatorStartup::getMicrosecondsSinceStart(), 'T' => PhabricatorStartup::getMicrosecondsSinceStart(),
)); ));
$multimeter->newEvent(
MultimeterEvent::TYPE_REQUEST_TIME,
$multimeter->getEventContext(),
PhabricatorStartup::getMicrosecondsSinceStart());
$access_log->write(); $access_log->write();
$multimeter->saveEvents(); $multimeter->saveEvents();
@ -171,16 +180,19 @@ abstract class AphrontApplicationConfiguration {
public function processRequest( public function processRequest(
AphrontRequest $request, AphrontRequest $request,
PhutilDeferredLog $access_log, PhutilDeferredLog $access_log,
AphrontHTTPSink $sink) { AphrontHTTPSink $sink,
MultimeterControl $multimeter) {
$this->setRequest($request); $this->setRequest($request);
list($controller, $uri_data) = $this->buildController(); list($controller, $uri_data) = $this->buildController();
$controller_class = get_class($controller);
$access_log->setData( $access_log->setData(
array( array(
'C' => get_class($controller), 'C' => $controller_class,
)); ));
$multimeter->setEventContext('web.'.$controller_class);
$request->setURIMap($uri_data); $request->setURIMap($uri_data);
$controller->setRequest($request); $controller->setRequest($request);
@ -198,6 +210,7 @@ abstract class AphrontApplicationConfiguration {
'u' => $request->getUser()->getUserName(), 'u' => $request->getUser()->getUserName(),
'P' => $request->getUser()->getPHID(), 'P' => $request->getUser()->getPHID(),
)); ));
$multimeter->setEventViewer('user.'.$request->getUser()->getPHID());
} }
if (!$response) { if (!$response) {

View file

@ -33,6 +33,15 @@ final class MultimeterSampleController extends MultimeterController {
$with = array(); $with = array();
foreach ($group_map as $key => $column) { foreach ($group_map as $key => $column) {
// Don't let non-admins filter by viewers, this feels a little too
// invasive of privacy.
if ($key == 'viewer') {
if (!$viewer->getIsAdmin()) {
continue;
}
}
$with[$key] = $request->getStrList($key); $with[$key] = $request->getStrList($key);
if ($with[$key]) { if ($with[$key]) {
$where[] = qsprintf( $where[] = qsprintf(
@ -58,6 +67,16 @@ final class MultimeterSampleController extends MultimeterController {
implode(', ', array_select_keys($group_map, $group))); implode(', ', array_select_keys($group_map, $group)));
$this->loadDimensions($data); $this->loadDimensions($data);
$phids = array();
foreach ($data as $row) {
$viewer_name = $this->getViewerDimension($row['eventViewerID'])
->getName();
$viewer_phid = $this->getEventViewerPHID($viewer_name);
if ($viewer_phid) {
$phids[] = $viewer_phid;
}
}
$handles = $viewer->loadHandles($phids);
$rows = array(); $rows = array();
foreach ($data as $row) { foreach ($data as $row) {
@ -75,13 +94,23 @@ final class MultimeterSampleController extends MultimeterController {
} }
if (isset($group['viewer'])) { if (isset($group['viewer'])) {
$viewer_col = $this->getViewerDimension($row['eventViewerID']) if ($viewer->getIsAdmin()) {
->getName(); $viewer_col = $this->getViewerDimension($row['eventViewerID'])
if (!$with['viewer']) { ->getName();
$viewer_col = $this->renderSelectionLink(
'viewer', $viewer_phid = $this->getEventViewerPHID($viewer_col);
$row['eventViewerID'], if ($viewer_phid) {
$viewer_col); $viewer_col = $handles[$viewer_phid]->getName();
}
if (!$with['viewer']) {
$viewer_col = $this->renderSelectionLink(
'viewer',
$row['eventViewerID'],
$viewer_col);
}
} else {
$viewer_col = phutil_tag('em', array(), pht('(Masked)'));
} }
} else { } else {
$viewer_col = $this->renderGroupingLink($group, 'viewer'); $viewer_col = $this->renderGroupingLink($group, 'viewer');
@ -145,11 +174,17 @@ final class MultimeterSampleController extends MultimeterController {
$host_col, $host_col,
$type_col, $type_col,
$label_col, $label_col,
MultimeterEvent::formatResourceCost(
$viewer,
$row['eventType'],
$row['totalCost'] / $row['N']),
MultimeterEvent::formatResourceCost( MultimeterEvent::formatResourceCost(
$viewer, $viewer,
$row['eventType'], $row['eventType'],
$row['totalCost']), $row['totalCost']),
$row['sampleRate'], ($row['N'] == 1)
? $row['sampleRate']
: '-',
phabricator_datetime($row['epoch'], $viewer), phabricator_datetime($row['epoch'], $viewer),
); );
} }
@ -164,6 +199,7 @@ final class MultimeterSampleController extends MultimeterController {
pht('Host'), pht('Host'),
pht('Type'), pht('Type'),
pht('Label'), pht('Label'),
pht('Avg'),
pht('Cost'), pht('Cost'),
pht('Rate'), pht('Rate'),
pht('Epoch'), pht('Epoch'),
@ -179,6 +215,7 @@ final class MultimeterSampleController extends MultimeterController {
'wide', 'wide',
'n', 'n',
'n', 'n',
'n',
null, null,
)); ));
@ -281,4 +318,11 @@ final class MultimeterSampleController extends MultimeterController {
); );
} }
private function getEventViewerPHID($viewer_name) {
if (!strncmp($viewer_name, 'user.', 5)) {
return substr($viewer_name, 5);
}
return null;
}
} }

View file

@ -149,6 +149,10 @@ final class MultimeterControl {
return $this; return $this;
} }
public function getEventContext() {
return $this->eventContext;
}
public function setEventViewer($viewer) { public function setEventViewer($viewer) {
$this->eventViewer = $viewer; $this->eventViewer = $viewer;
return $this; return $this;

View file

@ -3,6 +3,7 @@
final class MultimeterEvent extends MultimeterDAO { final class MultimeterEvent extends MultimeterDAO {
const TYPE_STATIC_RESOURCE = 0; const TYPE_STATIC_RESOURCE = 0;
const TYPE_REQUEST_TIME = 1;
protected $eventType; protected $eventType;
protected $eventLabelID; protected $eventLabelID;
@ -29,6 +30,8 @@ final class MultimeterEvent extends MultimeterDAO {
switch ($type) { switch ($type) {
case self::TYPE_STATIC_RESOURCE: case self::TYPE_STATIC_RESOURCE:
return pht('Static Resource'); return pht('Static Resource');
case self::TYPE_REQUEST_TIME:
return pht('Web Request');
} }
return pht('Unknown ("%s")', $type); return pht('Unknown ("%s")', $type);
@ -42,6 +45,8 @@ final class MultimeterEvent extends MultimeterDAO {
switch ($type) { switch ($type) {
case self::TYPE_STATIC_RESOURCE: case self::TYPE_STATIC_RESOURCE:
return pht('%s Req', new PhutilNumber($cost)); return pht('%s Req', new PhutilNumber($cost));
case self::TYPE_REQUEST_TIME:
return pht('%s us', new PhutilNumber($cost));
} }
return pht('%s Unit(s)', new PhutilNumber($cost)); return pht('%s Unit(s)', new PhutilNumber($cost));