@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add a basic web UI for intracluster sync logs

Summary: Depends on D19798. Ref T13216. This puts at least a basic UI on top of sync logs.

Test Plan:
Viewed logs from the web UI and exported data. Note that these syncs are somewhat simulated since I my local cluster is somewhat-faked (i.e., not actually multiple machines).

{F5995899}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13216

Differential Revision: https://secure.phabricator.com/D19799

+272 -4
+6
src/__phutil_library_map__.php
··· 992 992 'DiffusionSymbolController' => 'applications/diffusion/controller/DiffusionSymbolController.php', 993 993 'DiffusionSymbolDatasource' => 'applications/diffusion/typeahead/DiffusionSymbolDatasource.php', 994 994 'DiffusionSymbolQuery' => 'applications/diffusion/query/DiffusionSymbolQuery.php', 995 + 'DiffusionSyncLogListController' => 'applications/diffusion/controller/DiffusionSyncLogListController.php', 996 + 'DiffusionSyncLogListView' => 'applications/diffusion/view/DiffusionSyncLogListView.php', 997 + 'DiffusionSyncLogSearchEngine' => 'applications/diffusion/query/DiffusionSyncLogSearchEngine.php', 995 998 'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php', 996 999 'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php', 997 1000 'DiffusionTagTableView' => 'applications/diffusion/view/DiffusionTagTableView.php', ··· 6367 6370 'DiffusionSymbolController' => 'DiffusionController', 6368 6371 'DiffusionSymbolDatasource' => 'PhabricatorTypeaheadDatasource', 6369 6372 'DiffusionSymbolQuery' => 'PhabricatorOffsetPagedQuery', 6373 + 'DiffusionSyncLogListController' => 'DiffusionLogController', 6374 + 'DiffusionSyncLogListView' => 'AphrontView', 6375 + 'DiffusionSyncLogSearchEngine' => 'PhabricatorApplicationSearchEngine', 6370 6376 'DiffusionTagListController' => 'DiffusionController', 6371 6377 'DiffusionTagListView' => 'DiffusionView', 6372 6378 'DiffusionTagTableView' => 'DiffusionView',
+3
src/applications/diffusion/application/PhabricatorDiffusionApplication.php
··· 118 118 $this->getQueryRoutePattern() => 'DiffusionPushLogListController', 119 119 'view/(?P<id>\d+)/' => 'DiffusionPushEventViewController', 120 120 ), 121 + 'synclog/' => array( 122 + $this->getQueryRoutePattern() => 'DiffusionSyncLogListController', 123 + ), 121 124 'pulllog/' => array( 122 125 $this->getQueryRoutePattern() => 'DiffusionPullLogListController', 123 126 ),
+11 -2
src/applications/diffusion/controller/DiffusionRepositoryController.php
··· 370 370 $action_view->addAction( 371 371 id(new PhabricatorActionView()) 372 372 ->setName(pht('View Push Logs')) 373 - ->setIcon('fa-list-alt') 373 + ->setIcon('fa-upload') 374 374 ->setHref($push_uri)); 375 + 376 + $pull_uri = $this->getApplicationURI( 377 + 'synclog/?repositories='.$repository->getPHID()); 378 + 379 + $action_view->addAction( 380 + id(new PhabricatorActionView()) 381 + ->setName(pht('View Sync Logs')) 382 + ->setIcon('fa-exchange') 383 + ->setHref($pull_uri)); 375 384 } 376 385 377 386 $pull_uri = $this->getApplicationURI( ··· 380 389 $action_view->addAction( 381 390 id(new PhabricatorActionView()) 382 391 ->setName(pht('View Pull Logs')) 383 - ->setIcon('fa-list-alt') 392 + ->setIcon('fa-download') 384 393 ->setHref($pull_uri)); 385 394 386 395 return $action_view;
+17
src/applications/diffusion/controller/DiffusionSyncLogListController.php
··· 1 + <?php 2 + 3 + final class DiffusionSyncLogListController 4 + extends DiffusionLogController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + return id(new DiffusionSyncLogSearchEngine()) 8 + ->setController($this) 9 + ->buildResponse(); 10 + } 11 + 12 + protected function buildApplicationCrumbs() { 13 + return parent::buildApplicationCrumbs() 14 + ->addTextCrumb(pht('Sync Logs'), $this->getApplicationURI('synclog/')); 15 + } 16 + 17 + }
+154
src/applications/diffusion/query/DiffusionSyncLogSearchEngine.php
··· 1 + <?php 2 + 3 + final class DiffusionSyncLogSearchEngine 4 + extends PhabricatorApplicationSearchEngine { 5 + 6 + public function getResultTypeDescription() { 7 + return pht('Sync Logs'); 8 + } 9 + 10 + public function getApplicationClassName() { 11 + return 'PhabricatorDiffusionApplication'; 12 + } 13 + 14 + public function newQuery() { 15 + return new PhabricatorRepositorySyncEventQuery(); 16 + } 17 + 18 + protected function buildQueryFromParameters(array $map) { 19 + $query = $this->newQuery(); 20 + 21 + if ($map['repositoryPHIDs']) { 22 + $query->withRepositoryPHIDs($map['repositoryPHIDs']); 23 + } 24 + 25 + if ($map['createdStart'] || $map['createdEnd']) { 26 + $query->withEpochBetween( 27 + $map['createdStart'], 28 + $map['createdEnd']); 29 + } 30 + 31 + return $query; 32 + } 33 + 34 + protected function buildCustomSearchFields() { 35 + return array( 36 + id(new PhabricatorSearchDatasourceField()) 37 + ->setDatasource(new DiffusionRepositoryDatasource()) 38 + ->setKey('repositoryPHIDs') 39 + ->setAliases(array('repository', 'repositories', 'repositoryPHID')) 40 + ->setLabel(pht('Repositories')) 41 + ->setDescription( 42 + pht('Search for sync logs for specific repositories.')), 43 + id(new PhabricatorSearchDateField()) 44 + ->setLabel(pht('Created After')) 45 + ->setKey('createdStart'), 46 + id(new PhabricatorSearchDateField()) 47 + ->setLabel(pht('Created Before')) 48 + ->setKey('createdEnd'), 49 + ); 50 + } 51 + 52 + protected function newExportFields() { 53 + $viewer = $this->requireViewer(); 54 + 55 + $fields = array( 56 + id(new PhabricatorPHIDExportField()) 57 + ->setKey('repositoryPHID') 58 + ->setLabel(pht('Repository PHID')), 59 + id(new PhabricatorStringExportField()) 60 + ->setKey('repository') 61 + ->setLabel(pht('Repository')), 62 + id(new PhabricatorPHIDExportField()) 63 + ->setKey('devicePHID') 64 + ->setLabel(pht('Device PHID')), 65 + id(new PhabricatorPHIDExportField()) 66 + ->setKey('fromDevicePHID') 67 + ->setLabel(pht('From Device PHID')), 68 + id(new PhabricatorIntExportField()) 69 + ->setKey('deviceVersion') 70 + ->setLabel(pht('Device Version')), 71 + id(new PhabricatorIntExportField()) 72 + ->setKey('fromDeviceVersion') 73 + ->setLabel(pht('From Device Version')), 74 + id(new PhabricatorStringExportField()) 75 + ->setKey('result') 76 + ->setLabel(pht('Result')), 77 + id(new PhabricatorIntExportField()) 78 + ->setKey('code') 79 + ->setLabel(pht('Code')), 80 + id(new PhabricatorEpochExportField()) 81 + ->setKey('date') 82 + ->setLabel(pht('Date')), 83 + id(new PhabricatorIntExportField()) 84 + ->setKey('syncWait') 85 + ->setLabel(pht('Sync Wait')), 86 + ); 87 + 88 + return $fields; 89 + } 90 + 91 + protected function newExportData(array $events) { 92 + $viewer = $this->requireViewer(); 93 + 94 + $export = array(); 95 + foreach ($events as $event) { 96 + $repository = $event->getRepository(); 97 + $repository_phid = $repository->getPHID(); 98 + $repository_name = $repository->getDisplayName(); 99 + 100 + $map = array( 101 + 'repositoryPHID' => $repository_phid, 102 + 'repository' => $repository_name, 103 + 'devicePHID' => $event->getDevicePHID(), 104 + 'fromDevicePHID' => $event->getFromDevicePHID(), 105 + 'deviceVersion' => $event->getDeviceVersion(), 106 + 'fromDeviceVersion' => $event->getFromDeviceVersion(), 107 + 'result' => $event->getResultType(), 108 + 'code' => $event->getResultCode(), 109 + 'date' => $event->getEpoch(), 110 + 'syncWait' => $event->getSyncWait(), 111 + ); 112 + 113 + $export[] = $map; 114 + } 115 + 116 + return $export; 117 + } 118 + 119 + protected function getURI($path) { 120 + return '/diffusion/synclog/'.$path; 121 + } 122 + 123 + protected function getBuiltinQueryNames() { 124 + return array( 125 + 'all' => pht('All Sync Logs'), 126 + ); 127 + } 128 + 129 + public function buildSavedQueryFromBuiltin($query_key) { 130 + $query = $this->newSavedQuery(); 131 + $query->setQueryKey($query_key); 132 + 133 + switch ($query_key) { 134 + case 'all': 135 + return $query; 136 + } 137 + 138 + return parent::buildSavedQueryFromBuiltin($query_key); 139 + } 140 + 141 + protected function renderResultList( 142 + array $logs, 143 + PhabricatorSavedQuery $query, 144 + array $handles) { 145 + 146 + $table = id(new DiffusionSyncLogListView()) 147 + ->setViewer($this->requireViewer()) 148 + ->setLogs($logs); 149 + 150 + return id(new PhabricatorApplicationSearchResultView()) 151 + ->setTable($table); 152 + } 153 + 154 + }
+79
src/applications/diffusion/view/DiffusionSyncLogListView.php
··· 1 + <?php 2 + 3 + final class DiffusionSyncLogListView extends AphrontView { 4 + 5 + private $logs; 6 + 7 + public function setLogs(array $logs) { 8 + assert_instances_of($logs, 'PhabricatorRepositorySyncEvent'); 9 + $this->logs = $logs; 10 + return $this; 11 + } 12 + 13 + public function render() { 14 + $events = $this->logs; 15 + $viewer = $this->getViewer(); 16 + 17 + $rows = array(); 18 + foreach ($events as $event) { 19 + $repository = $event->getRepository(); 20 + $repository_link = phutil_tag( 21 + 'a', 22 + array( 23 + 'href' => $repository->getURI(), 24 + ), 25 + $repository->getDisplayName()); 26 + 27 + $event_id = $event->getID(); 28 + 29 + $sync_wait = pht('%sus', new PhutilNumber($event->getSyncWait())); 30 + 31 + $device_link = $viewer->renderHandle($event->getDevicePHID()); 32 + $from_device_link = $viewer->renderHandle($event->getFromDevicePHID()); 33 + 34 + $rows[] = array( 35 + $event_id, 36 + $repository_link, 37 + $device_link, 38 + $from_device_link, 39 + $event->getDeviceVersion(), 40 + $event->getFromDeviceVersion(), 41 + $event->getResultType(), 42 + $event->getResultCode(), 43 + phabricator_datetime($event->getEpoch(), $viewer), 44 + $sync_wait, 45 + ); 46 + } 47 + 48 + $table = id(new AphrontTableView($rows)) 49 + ->setHeaders( 50 + array( 51 + pht('Sync'), 52 + pht('Repository'), 53 + pht('Device'), 54 + pht('From Device'), 55 + pht('Version'), 56 + pht('From Version'), 57 + pht('Result'), 58 + pht('Code'), 59 + pht('Date'), 60 + pht('Sync Wait'), 61 + )) 62 + ->setColumnClasses( 63 + array( 64 + 'n', 65 + '', 66 + '', 67 + '', 68 + 'n', 69 + 'n', 70 + 'wide right', 71 + 'n', 72 + 'right', 73 + 'n right', 74 + )); 75 + 76 + return $table; 77 + } 78 + 79 + }
+1 -1
src/applications/repository/query/PhabricatorRepositorySyncEventQuery.php
··· 31 31 } 32 32 33 33 public function newResultObject() { 34 - return new PhabricatorRepositoryPullEvent(); 34 + return new PhabricatorRepositorySyncEvent(); 35 35 } 36 36 37 37 protected function loadPage() {
+1 -1
src/applications/repository/storage/PhabricatorRepositorySyncEvent.php
··· 65 65 } 66 66 67 67 public function setProperty($key, $value) { 68 - $this->properites[$key] = $value; 68 + $this->properties[$key] = $value; 69 69 return $this; 70 70 } 71 71