mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-23 15:22:41 +01:00
Move ConduitLogs to ApplicationSearch
Summary: Ref T9980. Start making this UI more useful and powerful so we can give administrators a better toolset for reacting to API changes. Fixes T9755. We were logging the caller, just not rendering it properly. Test Plan: {F1025799} Reviewers: chad Reviewed By: chad Maniphest Tasks: T9755, T9980 Differential Revision: https://secure.phabricator.com/D14779
This commit is contained in:
parent
00bd824781
commit
4a147dcbfb
6 changed files with 177 additions and 148 deletions
|
@ -1891,6 +1891,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitListController' => 'applications/conduit/controller/PhabricatorConduitListController.php',
|
'PhabricatorConduitListController' => 'applications/conduit/controller/PhabricatorConduitListController.php',
|
||||||
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
|
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
|
||||||
'PhabricatorConduitLogQuery' => 'applications/conduit/query/PhabricatorConduitLogQuery.php',
|
'PhabricatorConduitLogQuery' => 'applications/conduit/query/PhabricatorConduitLogQuery.php',
|
||||||
|
'PhabricatorConduitLogSearchEngine' => 'applications/conduit/query/PhabricatorConduitLogSearchEngine.php',
|
||||||
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
|
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
|
||||||
'PhabricatorConduitMethodQuery' => 'applications/conduit/query/PhabricatorConduitMethodQuery.php',
|
'PhabricatorConduitMethodQuery' => 'applications/conduit/query/PhabricatorConduitMethodQuery.php',
|
||||||
'PhabricatorConduitRequestExceptionHandler' => 'aphront/handler/PhabricatorConduitRequestExceptionHandler.php',
|
'PhabricatorConduitRequestExceptionHandler' => 'aphront/handler/PhabricatorConduitRequestExceptionHandler.php',
|
||||||
|
@ -6005,6 +6006,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitListController' => 'PhabricatorConduitController',
|
'PhabricatorConduitListController' => 'PhabricatorConduitController',
|
||||||
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
|
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
|
||||||
'PhabricatorConduitLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorConduitLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorConduitLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||||
'PhabricatorConduitMethodCallLog' => array(
|
'PhabricatorConduitMethodCallLog' => array(
|
||||||
'PhabricatorConduitDAO',
|
'PhabricatorConduitDAO',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
|
|
|
@ -48,7 +48,8 @@ final class PhabricatorConduitApplication extends PhabricatorApplication {
|
||||||
'/conduit/' => array(
|
'/conduit/' => array(
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorConduitListController',
|
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorConduitListController',
|
||||||
'method/(?P<method>[^/]+)/' => 'PhabricatorConduitConsoleController',
|
'method/(?P<method>[^/]+)/' => 'PhabricatorConduitConsoleController',
|
||||||
'log/' => 'PhabricatorConduitLogController',
|
'log/(?:query/(?P<queryKey>[^/]+)/)?' =>
|
||||||
|
'PhabricatorConduitLogController',
|
||||||
'log/view/(?P<view>[^/]+)/' => 'PhabricatorConduitLogController',
|
'log/view/(?P<view>[^/]+)/' => 'PhabricatorConduitLogController',
|
||||||
'token/' => 'PhabricatorConduitTokenController',
|
'token/' => 'PhabricatorConduitTokenController',
|
||||||
'token/edit/(?:(?P<id>\d+)/)?' =>
|
'token/edit/(?:(?P<id>\d+)/)?' =>
|
||||||
|
|
|
@ -110,19 +110,11 @@ final class PhabricatorConduitAPIController
|
||||||
|
|
||||||
$time_end = microtime(true);
|
$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
|
$log
|
||||||
->setCallerPHID(
|
->setCallerPHID(
|
||||||
isset($conduit_user)
|
isset($conduit_user)
|
||||||
? $conduit_user->getPHID()
|
? $conduit_user->getPHID()
|
||||||
: null)
|
: null)
|
||||||
->setConnectionID($connection_id)
|
|
||||||
->setError((string)$error_code)
|
->setError((string)$error_code)
|
||||||
->setDuration(1000000 * ($time_end - $time_start));
|
->setDuration(1000000 * ($time_end - $time_start));
|
||||||
|
|
||||||
|
|
|
@ -4,127 +4,9 @@ final class PhabricatorConduitLogController
|
||||||
extends PhabricatorConduitController {
|
extends PhabricatorConduitController {
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
$viewer = $request->getViewer();
|
return id(new PhabricatorConduitLogSearchEngine())
|
||||||
|
->setController($this)
|
||||||
$conn_table = new PhabricatorConduitConnectionLog();
|
->buildResponse();
|
||||||
$call_table = new PhabricatorConduitMethodCallLog();
|
|
||||||
|
|
||||||
$conn_r = $call_table->establishConnection('r');
|
|
||||||
|
|
||||||
$pager = new AphrontCursorPagerView();
|
|
||||||
$pager->readFromRequest($request);
|
|
||||||
$pager->setPageSize(500);
|
|
||||||
|
|
||||||
$query = id(new PhabricatorConduitLogQuery())
|
|
||||||
->setViewer($viewer);
|
|
||||||
|
|
||||||
$methods = $request->getStrList('methods');
|
|
||||||
if ($methods) {
|
|
||||||
$query->withMethods($methods);
|
|
||||||
}
|
|
||||||
|
|
||||||
$calls = $query->executeWithCursorPager($pager);
|
|
||||||
|
|
||||||
$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);
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeaderText(pht('Call Logs'))
|
|
||||||
->setTable($table);
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
|
||||||
$crumbs->addTextCrumb(pht('Call Logs'));
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
array(
|
|
||||||
$crumbs,
|
|
||||||
$box,
|
|
||||||
$pager,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'title' => pht('Conduit Logs'),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function renderCallTable(array $calls, array $conns) {
|
|
||||||
assert_instances_of($calls, 'PhabricatorConduitMethodCallLog');
|
|
||||||
assert_instances_of($conns, 'PhabricatorConduitConnectionLog');
|
|
||||||
|
|
||||||
$viewer = $this->getRequest()->getUser();
|
|
||||||
|
|
||||||
$methods = id(new PhabricatorConduitMethodQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->execute();
|
|
||||||
$methods = mpull($methods, null, 'getAPIMethodName');
|
|
||||||
|
|
||||||
$rows = array();
|
|
||||||
foreach ($calls as $call) {
|
|
||||||
$conn = idx($conns, $call->getConnectionID());
|
|
||||||
if ($conn) {
|
|
||||||
$name = $conn->getUserName();
|
|
||||||
$client = ' '.pht('(via %s)', $conn->getClient());
|
|
||||||
} else {
|
|
||||||
$name = null;
|
|
||||||
$client = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$method = idx($methods, $call->getMethod());
|
|
||||||
if ($method) {
|
|
||||||
switch ($method->getMethodStatus()) {
|
|
||||||
case ConduitAPIMethod::METHOD_STATUS_STABLE:
|
|
||||||
$status = null;
|
|
||||||
break;
|
|
||||||
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
|
|
||||||
$status = pht('Unstable');
|
|
||||||
break;
|
|
||||||
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
|
|
||||||
$status = pht('Deprecated');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$status = pht('Unknown');
|
|
||||||
}
|
|
||||||
|
|
||||||
$rows[] = array(
|
|
||||||
$call->getConnectionID(),
|
|
||||||
$name,
|
|
||||||
array($call->getMethod(), $client),
|
|
||||||
$status,
|
|
||||||
$call->getError(),
|
|
||||||
pht('%s us', new PhutilNumber($call->getDuration())),
|
|
||||||
phabricator_datetime($call->getDateCreated(), $viewer),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$table = id(new AphrontTableView($rows));
|
|
||||||
|
|
||||||
$table->setHeaders(
|
|
||||||
array(
|
|
||||||
pht('Connection'),
|
|
||||||
pht('User'),
|
|
||||||
pht('Method'),
|
|
||||||
pht('Status'),
|
|
||||||
pht('Error'),
|
|
||||||
pht('Duration'),
|
|
||||||
pht('Date'),
|
|
||||||
));
|
|
||||||
$table->setColumnClasses(
|
|
||||||
array(
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'wide',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'n',
|
|
||||||
'right',
|
|
||||||
));
|
|
||||||
return $table;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,33 +10,25 @@ final class PhabricatorConduitLogQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
public function newResultObject() {
|
||||||
$table = new PhabricatorConduitMethodCallLog();
|
return new PhabricatorConduitMethodCallLog();
|
||||||
$conn_r = $table->establishConnection('r');
|
|
||||||
|
|
||||||
$data = queryfx_all(
|
|
||||||
$conn_r,
|
|
||||||
'SELECT * FROM %T %Q %Q %Q',
|
|
||||||
$table->getTableName(),
|
|
||||||
$this->buildWhereClause($conn_r),
|
|
||||||
$this->buildOrderClause($conn_r),
|
|
||||||
$this->buildLimitClause($conn_r));
|
|
||||||
|
|
||||||
return $table->loadAllFromArray($data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
protected function loadPage() {
|
||||||
$where = array();
|
return $this->loadStandardPage($this->newResultObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
if ($this->methods) {
|
if ($this->methods) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'method IN (%Ls)',
|
'method IN (%Ls)',
|
||||||
$this->methods);
|
$this->methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
return $where;
|
||||||
return $this->formatWhereClause($where);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueryApplicationClass() {
|
public function getQueryApplicationClass() {
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorConduitLogSearchEngine
|
||||||
|
extends PhabricatorApplicationSearchEngine {
|
||||||
|
|
||||||
|
public function getResultTypeDescription() {
|
||||||
|
return pht('Conduit Logs');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getApplicationClassName() {
|
||||||
|
return 'PhabricatorConduitApplication';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newQuery() {
|
||||||
|
return new PhabricatorConduitLogQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildQueryFromParameters(array $map) {
|
||||||
|
$query = $this->newQuery();
|
||||||
|
|
||||||
|
if ($map['methods']) {
|
||||||
|
$query->withMethods($map['methods']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildCustomSearchFields() {
|
||||||
|
return array(
|
||||||
|
id(new PhabricatorSearchStringListField())
|
||||||
|
->setKey('methods')
|
||||||
|
->setLabel(pht('Methods'))
|
||||||
|
->setDescription(pht('Find calls to specific methods.')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getURI($path) {
|
||||||
|
return '/conduit/log/'.$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getBuiltinQueryNames() {
|
||||||
|
$names = array(
|
||||||
|
'all' => pht('All Logs'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildSavedQueryFromBuiltin($query_key) {
|
||||||
|
$query = $this->newSavedQuery();
|
||||||
|
$query->setQueryKey($query_key);
|
||||||
|
|
||||||
|
switch ($query_key) {
|
||||||
|
case 'all':
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderResultList(
|
||||||
|
array $logs,
|
||||||
|
PhabricatorSavedQuery $query,
|
||||||
|
array $handles) {
|
||||||
|
assert_instances_of($logs, 'PhabricatorConduitMethodCallLog');
|
||||||
|
$viewer = $this->requireViewer();
|
||||||
|
|
||||||
|
$methods = id(new PhabricatorConduitMethodQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->execute();
|
||||||
|
$methods = mpull($methods, null, 'getAPIMethodName');
|
||||||
|
|
||||||
|
Javelin::initBehavior('phabricator-tooltips');
|
||||||
|
|
||||||
|
$viewer = $this->requireViewer();
|
||||||
|
$rows = array();
|
||||||
|
foreach ($logs as $log) {
|
||||||
|
$caller_phid = $log->getCallerPHID();
|
||||||
|
|
||||||
|
if ($caller_phid) {
|
||||||
|
$caller = $viewer->renderHandle($caller_phid);
|
||||||
|
} else {
|
||||||
|
$caller = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = idx($methods, $log->getMethod());
|
||||||
|
if ($method) {
|
||||||
|
$method_status = $method->getMethodStatus();
|
||||||
|
} else {
|
||||||
|
$method_status = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($method_status) {
|
||||||
|
case ConduitAPIMethod::METHOD_STATUS_STABLE:
|
||||||
|
$status = null;
|
||||||
|
break;
|
||||||
|
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
|
||||||
|
$status = id(new PHUIIconView())
|
||||||
|
->setIconFont('fa-exclamation-triangle yellow')
|
||||||
|
->addSigil('has-tooltip')
|
||||||
|
->setMetadata(
|
||||||
|
array(
|
||||||
|
'tip' => pht('Unstable'),
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
|
||||||
|
$status = id(new PHUIIconView())
|
||||||
|
->setIconFont('fa-exclamation-triangle red')
|
||||||
|
->addSigil('has-tooltip')
|
||||||
|
->setMetadata(
|
||||||
|
array(
|
||||||
|
'tip' => pht('Deprecated'),
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$status = id(new PHUIIconView())
|
||||||
|
->setIconFont('fa-question-circle')
|
||||||
|
->addSigil('has-tooltip')
|
||||||
|
->setMetadata(
|
||||||
|
array(
|
||||||
|
'tip' => pht('Unknown ("%s")', $status),
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
$status,
|
||||||
|
$log->getMethod(),
|
||||||
|
$caller,
|
||||||
|
$log->getError(),
|
||||||
|
pht('%s us', new PhutilNumber($log->getDuration())),
|
||||||
|
phabricator_datetime($log->getDateCreated(), $viewer),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = id(new AphrontTableView($rows))
|
||||||
|
->setHeaders(
|
||||||
|
array(
|
||||||
|
null,
|
||||||
|
pht('Method'),
|
||||||
|
pht('Caller'),
|
||||||
|
pht('Error'),
|
||||||
|
pht('Duration'),
|
||||||
|
pht('Date'),
|
||||||
|
))
|
||||||
|
->setColumnClasses(
|
||||||
|
array(
|
||||||
|
null,
|
||||||
|
'pri',
|
||||||
|
null,
|
||||||
|
'wide right',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
));
|
||||||
|
|
||||||
|
return id(new PhabricatorApplicationSearchResultView())
|
||||||
|
->setTable($table)
|
||||||
|
->setNoDataString(pht('No matching calls in log.'));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue