From 77a5a3ab0088c0f515cc234c80aedff90dfe7e91 Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 30 Nov 2011 15:17:37 -0800 Subject: [PATCH] Add a basic Conduit log view Summary: The conduit access to Differential kind of sucks and we want to break back-compat in order to fix it (see D1114). To make it easier to pull this off, I want to build out the Conduit logging a bit so administrators can identify which users are making deprecated calls. We should probably build a little more infrastructure around this too (API versions?), but this is at least a reasonable step forward which gives us more insight into the use of Conduit and more tools to smooth the deprecation process. This initial commit is super basic but the interface currently says "stuff", I'll build this out a little more in a bit. Test Plan: Looked at call logs. Reviewers: btrahan, nh, jungejason Reviewed By: btrahan CC: aran, btrahan Differential Revision: 1144 --- ...AphrontDefaultApplicationConfiguration.php | 1 + .../log/PhabricatorConduitLogController.php | 113 +++++++++++++++++- .../conduit/controller/log/__init__.php | 11 ++ 3 files changed, 121 insertions(+), 4 deletions(-) diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index e60334c913..507ad4ef73 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -83,6 +83,7 @@ class AphrontDefaultApplicationConfiguration '$' => 'PhabricatorConduitConsoleController', 'method/(?P[^/]+)$' => 'PhabricatorConduitConsoleController', 'log/$' => 'PhabricatorConduitLogController', + 'log/view/(?P[^/]+)/$' => 'PhabricatorConduitLogController', 'token/$' => 'PhabricatorConduitTokenController', ), '/api/(?P[^/]+)$' => 'PhabricatorConduitAPIController', diff --git a/src/applications/conduit/controller/log/PhabricatorConduitLogController.php b/src/applications/conduit/controller/log/PhabricatorConduitLogController.php index 74206aa9aa..18139313e0 100644 --- a/src/applications/conduit/controller/log/PhabricatorConduitLogController.php +++ b/src/applications/conduit/controller/log/PhabricatorConduitLogController.php @@ -21,11 +21,116 @@ */ class PhabricatorConduitLogController extends PhabricatorConduitController { - public function processRequest() { + private $view; - return $this->buildStandardPageResponse('stuff', array( - 'title' => 'Conduit Logs', - 'tab' => 'logs', + public function willProcessRequest(array $data) { + $this->view = idx($data, 'view'); + } + + public function processRequest() { + $request = $this->getRequest(); + + $nav = new AphrontSideNavView(); + $links = array( + 'calls' => 'All Calls', + ); + + if (empty($links[$this->view])) { + $this->view = key($links); + } + + foreach ($links as $slug => $name) { + $nav->addNavItem( + phutil_render_tag( + 'a', + array( + 'href' => '/conduit/log/view/'.$slug.'/', + 'class' => ($slug == $this->view) + ? 'aphront-side-nav-selected' + : null, + ), + phutil_escape_html($name))); + } + + $conn_table = new PhabricatorConduitConnectionLog(); + $call_table = new PhabricatorConduitMethodCallLog(); + + $conn_r = $call_table->establishConnection('r'); + + $pager = new AphrontPagerView(); + $pager->setOffset($request->getInt('page')); + $calls = $call_table->loadAllWhere( + '1 = 1 ORDER BY id DESC LIMIT %d, %d', + $pager->getOffset(), + $pager->getPageSize() + 1); + $calls = $pager->sliceResults($calls); + $pager->setURI(new PhutilURI('/conduit/log/view/'.$this->view.'/'), 'page'); + + $min = $pager->getOffset() + 1; + $max = ($min + count($calls) - 1); + + $conn_ids = array_filter(mpull($calls, 'getConnectionID')); + $conns = array(); + if ($conn_ids) { + $conns = $conn_table->loadAllWhere( + 'id IN (%Ld)', + $conn_ids); + } + + $table = $this->renderCallTable($calls, $conns); + $panel = new AphrontPanelView(); + $panel->setHeader('Conduit Method Calls ('.$min.'-'.$max.')'); + $panel->appendChild($table); + $panel->appendChild($pager); + $nav->appendChild($panel); + + return $this->buildStandardPageResponse( + $nav, + array( + 'title' => 'Conduit Logs', + 'tab' => 'logs', )); } + + private function renderCallTable(array $calls, array $conns) { + $user = $this->getRequest()->getUser(); + + $rows = array(); + foreach ($calls as $call) { + $conn = idx($conns, $call->getConnectionID()); + if (!$conn) { + // If there's no connection, use an empty object. + $conn = new PhabricatorConduitConnectionLog(); + } + $rows[] = array( + $call->getConnectionID(), + phutil_escape_html($conn->getUserName()), + phutil_escape_html($call->getMethod()), + phutil_escape_html($call->getError()), + number_format($call->getDuration()).' us', + phabricator_datetime($call->getDateCreated(), $user), + ); + } + $table = new AphrontTableView($rows); + $table->setHeaders( + array( + 'Connection', + 'User', + 'Method', + 'Error', + 'Duration', + 'Date', + )); + $table->setColumnClasses( + array( + '', + '', + 'wide', + '', + 'n', + 'right', + )); + return $table; + } + } diff --git a/src/applications/conduit/controller/log/__init__.php b/src/applications/conduit/controller/log/__init__.php index cbe5f7c474..d1643a89c4 100644 --- a/src/applications/conduit/controller/log/__init__.php +++ b/src/applications/conduit/controller/log/__init__.php @@ -7,6 +7,17 @@ phutil_require_module('phabricator', 'applications/conduit/controller/base'); +phutil_require_module('phabricator', 'applications/conduit/storage/connectionlog'); +phutil_require_module('phabricator', 'applications/conduit/storage/methodcalllog'); +phutil_require_module('phabricator', 'view/control/pager'); +phutil_require_module('phabricator', 'view/control/table'); +phutil_require_module('phabricator', 'view/layout/panel'); +phutil_require_module('phabricator', 'view/layout/sidenav'); +phutil_require_module('phabricator', 'view/utils'); + +phutil_require_module('phutil', 'markup'); +phutil_require_module('phutil', 'parser/uri'); +phutil_require_module('phutil', 'utils'); phutil_require_source('PhabricatorConduitLogController.php');