Skip to content

Commit 4a147dc

Browse files
author
epriestley
committed
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
1 parent 00bd824 commit 4a147dc

File tree

6 files changed

+176
-147
lines changed

6 files changed

+176
-147
lines changed

src/__phutil_library_map__.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,6 +1891,7 @@
18911891
'PhabricatorConduitListController' => 'applications/conduit/controller/PhabricatorConduitListController.php',
18921892
'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
18931893
'PhabricatorConduitLogQuery' => 'applications/conduit/query/PhabricatorConduitLogQuery.php',
1894+
'PhabricatorConduitLogSearchEngine' => 'applications/conduit/query/PhabricatorConduitLogSearchEngine.php',
18941895
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
18951896
'PhabricatorConduitMethodQuery' => 'applications/conduit/query/PhabricatorConduitMethodQuery.php',
18961897
'PhabricatorConduitRequestExceptionHandler' => 'aphront/handler/PhabricatorConduitRequestExceptionHandler.php',
@@ -6005,6 +6006,7 @@
60056006
'PhabricatorConduitListController' => 'PhabricatorConduitController',
60066007
'PhabricatorConduitLogController' => 'PhabricatorConduitController',
60076008
'PhabricatorConduitLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
6009+
'PhabricatorConduitLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
60086010
'PhabricatorConduitMethodCallLog' => array(
60096011
'PhabricatorConduitDAO',
60106012
'PhabricatorPolicyInterface',

src/applications/conduit/application/PhabricatorConduitApplication.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public function getRoutes() {
4848
'/conduit/' => array(
4949
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhabricatorConduitListController',
5050
'method/(?P<method>[^/]+)/' => 'PhabricatorConduitConsoleController',
51-
'log/' => 'PhabricatorConduitLogController',
51+
'log/(?:query/(?P<queryKey>[^/]+)/)?' =>
52+
'PhabricatorConduitLogController',
5253
'log/view/(?P<view>[^/]+)/' => 'PhabricatorConduitLogController',
5354
'token/' => 'PhabricatorConduitTokenController',
5455
'token/edit/(?:(?P<id>\d+)/)?' =>

src/applications/conduit/controller/PhabricatorConduitAPIController.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,11 @@ public function handleRequest(AphrontRequest $request) {
110110

111111
$time_end = microtime(true);
112112

113-
$connection_id = null;
114-
if (idx($metadata, 'connectionID')) {
115-
$connection_id = $metadata['connectionID'];
116-
} else if (($method == 'conduit.connect') && $result) {
117-
$connection_id = idx($result, 'connectionID');
118-
}
119-
120113
$log
121114
->setCallerPHID(
122115
isset($conduit_user)
123116
? $conduit_user->getPHID()
124117
: null)
125-
->setConnectionID($connection_id)
126118
->setError((string)$error_code)
127119
->setDuration(1000000 * ($time_end - $time_start));
128120

src/applications/conduit/controller/PhabricatorConduitLogController.php

Lines changed: 3 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -4,127 +4,9 @@ final class PhabricatorConduitLogController
44
extends PhabricatorConduitController {
55

66
public function handleRequest(AphrontRequest $request) {
7-
$viewer = $request->getViewer();
8-
9-
$conn_table = new PhabricatorConduitConnectionLog();
10-
$call_table = new PhabricatorConduitMethodCallLog();
11-
12-
$conn_r = $call_table->establishConnection('r');
13-
14-
$pager = new AphrontCursorPagerView();
15-
$pager->readFromRequest($request);
16-
$pager->setPageSize(500);
17-
18-
$query = id(new PhabricatorConduitLogQuery())
19-
->setViewer($viewer);
20-
21-
$methods = $request->getStrList('methods');
22-
if ($methods) {
23-
$query->withMethods($methods);
24-
}
25-
26-
$calls = $query->executeWithCursorPager($pager);
27-
28-
$conn_ids = array_filter(mpull($calls, 'getConnectionID'));
29-
$conns = array();
30-
if ($conn_ids) {
31-
$conns = $conn_table->loadAllWhere(
32-
'id IN (%Ld)',
33-
$conn_ids);
34-
}
35-
36-
$table = $this->renderCallTable($calls, $conns);
37-
$box = id(new PHUIObjectBoxView())
38-
->setHeaderText(pht('Call Logs'))
39-
->setTable($table);
40-
41-
$crumbs = $this->buildApplicationCrumbs();
42-
$crumbs->addTextCrumb(pht('Call Logs'));
43-
44-
return $this->buildApplicationPage(
45-
array(
46-
$crumbs,
47-
$box,
48-
$pager,
49-
),
50-
array(
51-
'title' => pht('Conduit Logs'),
52-
));
53-
}
54-
55-
private function renderCallTable(array $calls, array $conns) {
56-
assert_instances_of($calls, 'PhabricatorConduitMethodCallLog');
57-
assert_instances_of($conns, 'PhabricatorConduitConnectionLog');
58-
59-
$viewer = $this->getRequest()->getUser();
60-
61-
$methods = id(new PhabricatorConduitMethodQuery())
62-
->setViewer($viewer)
63-
->execute();
64-
$methods = mpull($methods, null, 'getAPIMethodName');
65-
66-
$rows = array();
67-
foreach ($calls as $call) {
68-
$conn = idx($conns, $call->getConnectionID());
69-
if ($conn) {
70-
$name = $conn->getUserName();
71-
$client = ' '.pht('(via %s)', $conn->getClient());
72-
} else {
73-
$name = null;
74-
$client = null;
75-
}
76-
77-
$method = idx($methods, $call->getMethod());
78-
if ($method) {
79-
switch ($method->getMethodStatus()) {
80-
case ConduitAPIMethod::METHOD_STATUS_STABLE:
81-
$status = null;
82-
break;
83-
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
84-
$status = pht('Unstable');
85-
break;
86-
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
87-
$status = pht('Deprecated');
88-
break;
89-
}
90-
} else {
91-
$status = pht('Unknown');
92-
}
93-
94-
$rows[] = array(
95-
$call->getConnectionID(),
96-
$name,
97-
array($call->getMethod(), $client),
98-
$status,
99-
$call->getError(),
100-
pht('%s us', new PhutilNumber($call->getDuration())),
101-
phabricator_datetime($call->getDateCreated(), $viewer),
102-
);
103-
}
104-
105-
$table = id(new AphrontTableView($rows));
106-
107-
$table->setHeaders(
108-
array(
109-
pht('Connection'),
110-
pht('User'),
111-
pht('Method'),
112-
pht('Status'),
113-
pht('Error'),
114-
pht('Duration'),
115-
pht('Date'),
116-
));
117-
$table->setColumnClasses(
118-
array(
119-
'',
120-
'',
121-
'wide',
122-
'',
123-
'',
124-
'n',
125-
'right',
126-
));
127-
return $table;
7+
return id(new PhabricatorConduitLogSearchEngine())
8+
->setController($this)
9+
->buildResponse();
12810
}
12911

13012
}

src/applications/conduit/query/PhabricatorConduitLogQuery.php

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,25 @@ public function withMethods(array $methods) {
1010
return $this;
1111
}
1212

13+
public function newResultObject() {
14+
return new PhabricatorConduitMethodCallLog();
15+
}
16+
1317
protected function loadPage() {
14-
$table = new PhabricatorConduitMethodCallLog();
15-
$conn_r = $table->establishConnection('r');
16-
17-
$data = queryfx_all(
18-
$conn_r,
19-
'SELECT * FROM %T %Q %Q %Q',
20-
$table->getTableName(),
21-
$this->buildWhereClause($conn_r),
22-
$this->buildOrderClause($conn_r),
23-
$this->buildLimitClause($conn_r));
24-
25-
return $table->loadAllFromArray($data);
18+
return $this->loadStandardPage($this->newResultObject());
2619
}
2720

28-
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
29-
$where = array();
21+
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
22+
$where = parent::buildWhereClauseParts($conn);
3023

3124
if ($this->methods) {
3225
$where[] = qsprintf(
33-
$conn_r,
26+
$conn,
3427
'method IN (%Ls)',
3528
$this->methods);
3629
}
3730

38-
$where[] = $this->buildPagingClause($conn_r);
39-
return $this->formatWhereClause($where);
31+
return $where;
4032
}
4133

4234
public function getQueryApplicationClass() {
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<?php
2+
3+
final class PhabricatorConduitLogSearchEngine
4+
extends PhabricatorApplicationSearchEngine {
5+
6+
public function getResultTypeDescription() {
7+
return pht('Conduit Logs');
8+
}
9+
10+
public function getApplicationClassName() {
11+
return 'PhabricatorConduitApplication';
12+
}
13+
14+
public function newQuery() {
15+
return new PhabricatorConduitLogQuery();
16+
}
17+
18+
protected function buildQueryFromParameters(array $map) {
19+
$query = $this->newQuery();
20+
21+
if ($map['methods']) {
22+
$query->withMethods($map['methods']);
23+
}
24+
25+
return $query;
26+
}
27+
28+
protected function buildCustomSearchFields() {
29+
return array(
30+
id(new PhabricatorSearchStringListField())
31+
->setKey('methods')
32+
->setLabel(pht('Methods'))
33+
->setDescription(pht('Find calls to specific methods.')),
34+
);
35+
}
36+
37+
protected function getURI($path) {
38+
return '/conduit/log/'.$path;
39+
}
40+
41+
protected function getBuiltinQueryNames() {
42+
$names = array(
43+
'all' => pht('All Logs'),
44+
);
45+
46+
return $names;
47+
}
48+
49+
public function buildSavedQueryFromBuiltin($query_key) {
50+
$query = $this->newSavedQuery();
51+
$query->setQueryKey($query_key);
52+
53+
switch ($query_key) {
54+
case 'all':
55+
return $query;
56+
}
57+
58+
return parent::buildSavedQueryFromBuiltin($query_key);
59+
}
60+
61+
protected function renderResultList(
62+
array $logs,
63+
PhabricatorSavedQuery $query,
64+
array $handles) {
65+
assert_instances_of($logs, 'PhabricatorConduitMethodCallLog');
66+
$viewer = $this->requireViewer();
67+
68+
$methods = id(new PhabricatorConduitMethodQuery())
69+
->setViewer($viewer)
70+
->execute();
71+
$methods = mpull($methods, null, 'getAPIMethodName');
72+
73+
Javelin::initBehavior('phabricator-tooltips');
74+
75+
$viewer = $this->requireViewer();
76+
$rows = array();
77+
foreach ($logs as $log) {
78+
$caller_phid = $log->getCallerPHID();
79+
80+
if ($caller_phid) {
81+
$caller = $viewer->renderHandle($caller_phid);
82+
} else {
83+
$caller = null;
84+
}
85+
86+
$method = idx($methods, $log->getMethod());
87+
if ($method) {
88+
$method_status = $method->getMethodStatus();
89+
} else {
90+
$method_status = null;
91+
}
92+
93+
switch ($method_status) {
94+
case ConduitAPIMethod::METHOD_STATUS_STABLE:
95+
$status = null;
96+
break;
97+
case ConduitAPIMethod::METHOD_STATUS_UNSTABLE:
98+
$status = id(new PHUIIconView())
99+
->setIconFont('fa-exclamation-triangle yellow')
100+
->addSigil('has-tooltip')
101+
->setMetadata(
102+
array(
103+
'tip' => pht('Unstable'),
104+
));
105+
break;
106+
case ConduitAPIMethod::METHOD_STATUS_DEPRECATED:
107+
$status = id(new PHUIIconView())
108+
->setIconFont('fa-exclamation-triangle red')
109+
->addSigil('has-tooltip')
110+
->setMetadata(
111+
array(
112+
'tip' => pht('Deprecated'),
113+
));
114+
break;
115+
default:
116+
$status = id(new PHUIIconView())
117+
->setIconFont('fa-question-circle')
118+
->addSigil('has-tooltip')
119+
->setMetadata(
120+
array(
121+
'tip' => pht('Unknown ("%s")', $status),
122+
));
123+
break;
124+
}
125+
126+
$rows[] = array(
127+
$status,
128+
$log->getMethod(),
129+
$caller,
130+
$log->getError(),
131+
pht('%s us', new PhutilNumber($log->getDuration())),
132+
phabricator_datetime($log->getDateCreated(), $viewer),
133+
);
134+
}
135+
136+
$table = id(new AphrontTableView($rows))
137+
->setHeaders(
138+
array(
139+
null,
140+
pht('Method'),
141+
pht('Caller'),
142+
pht('Error'),
143+
pht('Duration'),
144+
pht('Date'),
145+
))
146+
->setColumnClasses(
147+
array(
148+
null,
149+
'pri',
150+
null,
151+
'wide right',
152+
null,
153+
null,
154+
));
155+
156+
return id(new PhabricatorApplicationSearchResultView())
157+
->setTable($table)
158+
->setNoDataString(pht('No matching calls in log.'));
159+
}
160+
}

0 commit comments

Comments
 (0)