diff --git a/src/applications/multimeter/controller/MultimeterSampleController.php b/src/applications/multimeter/controller/MultimeterSampleController.php index ee707c34db..1b60022eec 100644 --- a/src/applications/multimeter/controller/MultimeterSampleController.php +++ b/src/applications/multimeter/controller/MultimeterSampleController.php @@ -8,15 +8,7 @@ final class MultimeterSampleController extends MultimeterController { public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - - $group_map = array( - 'type' => 'eventType', - 'host' => 'eventHostID', - 'context' => 'eventContextID', - 'viewer' => 'eventViewerID', - 'request' => 'requestKey', - 'label' => 'eventLabelID', - ); + $group_map = $this->getColumnMap(); $group = explode('.', $request->getStr('group')); $group = array_intersect($group, array_keys($group_map)); @@ -31,17 +23,38 @@ final class MultimeterSampleController extends MultimeterController { $table = new MultimeterEvent(); $conn = $table->establishConnection('r'); + + $where = array(); + $where[] = qsprintf( + $conn, + 'epoch >= %d AND epoch <= %d', + $ago, + $now); + + $with = array(); + foreach ($group_map as $key => $column) { + $with[$key] = $request->getStrList($key); + if ($with[$key]) { + $where[] = qsprintf( + $conn, + '%T IN (%Ls)', + $column, + $with[$key]); + } + } + + $where = '('.implode(') AND (', $where).')'; + $data = queryfx_all( $conn, 'SELECT *, count(*) N, SUM(sampleRate * resourceCost) as totalCost FROM %T - WHERE epoch >= %d AND epoch <= %d + WHERE %Q GROUP BY %Q ORDER BY totalCost DESC, MAX(id) DESC LIMIT 100', $table->getTableName(), - $ago, - $now, + $where, implode(', ', array_select_keys($group_map, $group))); $this->loadDimensions($data); @@ -51,6 +64,12 @@ final class MultimeterSampleController extends MultimeterController { if (isset($group['request'])) { $request_col = $row['requestKey']; + if (!$with['request']) { + $request_col = $this->renderSelectionLink( + 'request', + $row['requestKey'], + $request_col); + } } else { $request_col = $this->renderGroupingLink($group, 'request'); } @@ -58,6 +77,12 @@ final class MultimeterSampleController extends MultimeterController { if (isset($group['viewer'])) { $viewer_col = $this->getViewerDimension($row['eventViewerID']) ->getName(); + if (!$with['viewer']) { + $viewer_col = $this->renderSelectionLink( + 'viewer', + $row['eventViewerID'], + $viewer_col); + } } else { $viewer_col = $this->renderGroupingLink($group, 'viewer'); } @@ -65,6 +90,12 @@ final class MultimeterSampleController extends MultimeterController { if (isset($group['context'])) { $context_col = $this->getContextDimension($row['eventContextID']) ->getName(); + if (!$with['context']) { + $context_col = $this->renderSelectionLink( + 'context', + $row['eventContextID'], + $context_col); + } } else { $context_col = $this->renderGroupingLink($group, 'context'); } @@ -72,6 +103,12 @@ final class MultimeterSampleController extends MultimeterController { if (isset($group['host'])) { $host_col = $this->getHostDimension($row['eventHostID']) ->getName(); + if (!$with['host']) { + $host_col = $this->renderSelectionLink( + 'host', + $row['eventHostID'], + $host_col); + } } else { $host_col = $this->renderGroupingLink($group, 'host'); } @@ -79,10 +116,25 @@ final class MultimeterSampleController extends MultimeterController { if (isset($group['label'])) { $label_col = $this->getLabelDimension($row['eventLabelID']) ->getName(); + if (!$with['label']) { + $label_col = $this->renderSelectionLink( + 'label', + $row['eventLabelID'], + $label_col); + } } else { $label_col = $this->renderGroupingLink($group, 'label'); } + if ($with['type']) { + $type_col = MultimeterEvent::getEventTypeName($row['eventType']); + } else { + $type_col = $this->renderSelectionLink( + 'type', + $row['eventType'], + MultimeterEvent::getEventTypeName($row['eventType'])); + } + $rows[] = array( ($row['N'] == 1) ? $row['id'] @@ -91,7 +143,7 @@ final class MultimeterSampleController extends MultimeterController { $viewer_col, $context_col, $host_col, - MultimeterEvent::getEventTypeName($row['eventType']), + $type_col, $label_col, MultimeterEvent::formatResourceCost( $viewer, @@ -139,7 +191,9 @@ final class MultimeterSampleController extends MultimeterController { ->appendChild($table); $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Samples'), $this->getGroupURI(array())); + $crumbs->addTextCrumb( + pht('Samples'), + $this->getGroupURI(array(), true)); $crumb_map = array( 'host' => pht('By Host'), @@ -157,7 +211,7 @@ final class MultimeterSampleController extends MultimeterController { $parts[$item] = $item; $crumbs->addTextCrumb( idx($crumb_map, $item, $item), - $this->getGroupURI($parts)); + $this->getGroupURI($parts, true)); } return $this->buildApplicationPage( @@ -183,12 +237,48 @@ final class MultimeterSampleController extends MultimeterController { pht('(All)')); } - private function getGroupURI(array $group) { + private function getGroupURI(array $group, $wipe = false) { unset($group['type']); $uri = clone $this->getRequest()->getRequestURI(); - $uri->setQueryParam('group', implode('.', $group)); + + $group = implode('.', $group); + if (!strlen($group)) { + $group = null; + } + $uri->setQueryParam('group', $group); + + if ($wipe) { + foreach ($this->getColumnMap() as $key => $column) { + $uri->setQueryParam($key, null); + } + } + return $uri; } + private function renderSelectionLink($key, $value, $link_text) { + $value = (array)$value; + + $uri = clone $this->getRequest()->getRequestURI(); + $uri->setQueryParam($key, implode(',', $value)); + + return phutil_tag( + 'a', + array( + 'href' => $uri, + ), + $link_text); + } + + private function getColumnMap() { + return array( + 'type' => 'eventType', + 'host' => 'eventHostID', + 'context' => 'eventContextID', + 'viewer' => 'eventViewerID', + 'request' => 'requestKey', + 'label' => 'eventLabelID', + ); + } }