mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Improve web tools for viewing daemons
Summary: - Provides an "all daemons" view to look at more than the first 15 daemons. - Provides a "combined log" view with a large page size, to quickly look at the log across all the daemons, making it easier to find issues when you have a bunch of the same daemon and only one is having issues. - When viewing the web console on the same host as a daemon, show whether it's running or not. Test Plan: Clicked the various daemon log interfaces. Reviewed By: aran Reviewers: jungejason, tuomaspelkonen, aran CC: aran Differential Revision: 215
This commit is contained in:
parent
8370f93048
commit
6229cdadd8
16 changed files with 428 additions and 77 deletions
|
@ -271,12 +271,16 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog',
|
'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/methodcalllog',
|
||||||
'PhabricatorController' => 'applications/base/controller/base',
|
'PhabricatorController' => 'applications/base/controller/base',
|
||||||
'PhabricatorDaemon' => 'infrastructure/daemon/base',
|
'PhabricatorDaemon' => 'infrastructure/daemon/base',
|
||||||
|
'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/combined',
|
||||||
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
|
'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/console',
|
||||||
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
|
'PhabricatorDaemonControl' => 'infrastructure/daemon/control',
|
||||||
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
|
'PhabricatorDaemonController' => 'applications/daemon/controller/base',
|
||||||
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/base',
|
'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/base',
|
||||||
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/log',
|
'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/log',
|
||||||
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/event',
|
'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/event',
|
||||||
|
'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/daemonlogevents',
|
||||||
|
'PhabricatorDaemonLogListController' => 'applications/daemon/controller/loglist',
|
||||||
|
'PhabricatorDaemonLogListView' => 'applications/daemon/view/daemonloglist',
|
||||||
'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/logview',
|
'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/logview',
|
||||||
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
|
'PhabricatorDaemonReference' => 'infrastructure/daemon/control/reference',
|
||||||
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
|
'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/timeline',
|
||||||
|
@ -675,11 +679,15 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
|
'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
|
||||||
'PhabricatorController' => 'AphrontController',
|
'PhabricatorController' => 'AphrontController',
|
||||||
'PhabricatorDaemon' => 'PhutilDaemon',
|
'PhabricatorDaemon' => 'PhutilDaemon',
|
||||||
|
'PhabricatorDaemonCombinedLogController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonController' => 'PhabricatorController',
|
'PhabricatorDaemonController' => 'PhabricatorController',
|
||||||
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
|
'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
|
||||||
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
|
'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
|
||||||
|
'PhabricatorDaemonLogEventsView' => 'AphrontView',
|
||||||
|
'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
|
||||||
|
'PhabricatorDaemonLogListView' => 'AphrontView',
|
||||||
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController',
|
||||||
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
|
'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController',
|
||||||
|
|
|
@ -231,6 +231,8 @@ class AphrontDefaultApplicationConfiguration
|
||||||
'/daemon/' => array(
|
'/daemon/' => array(
|
||||||
'task/(?P<id>\d+)/$' => 'PhabricatorWorkerTaskDetailController',
|
'task/(?P<id>\d+)/$' => 'PhabricatorWorkerTaskDetailController',
|
||||||
'log/' => array(
|
'log/' => array(
|
||||||
|
'$' => 'PhabricatorDaemonLogListController',
|
||||||
|
'combined/$' => 'PhabricatorDaemonCombinedLogController',
|
||||||
'(?P<id>\d+)/$' => 'PhabricatorDaemonLogViewController',
|
'(?P<id>\d+)/$' => 'PhabricatorDaemonLogViewController',
|
||||||
),
|
),
|
||||||
'timeline/$' => 'PhabricatorDaemonTimelineConsoleController',
|
'timeline/$' => 'PhabricatorDaemonTimelineConsoleController',
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorDaemonCombinedLogController
|
||||||
|
extends PhabricatorDaemonController {
|
||||||
|
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
$pager = new AphrontPagerView();
|
||||||
|
$pager->setOffset($request->getInt('page'));
|
||||||
|
$pager->setPageSize(1000);
|
||||||
|
|
||||||
|
$events = id(new PhabricatorDaemonLogEvent())->loadAllWhere(
|
||||||
|
'1 = 1 ORDER BY id DESC LIMIT %d, %d',
|
||||||
|
$pager->getOffset(),
|
||||||
|
$pager->getPageSize() + 1);
|
||||||
|
|
||||||
|
$events = $pager->sliceResults($events);
|
||||||
|
$pager->setURI($request->getRequestURI(), 'page');
|
||||||
|
|
||||||
|
$event_view = new PhabricatorDaemonLogEventsView();
|
||||||
|
$event_view->setEvents($events);
|
||||||
|
$event_view->setCombinedLog(true);
|
||||||
|
|
||||||
|
$log_panel = new AphrontPanelView();
|
||||||
|
$log_panel->setHeader('Combined Daemon Logs');
|
||||||
|
$log_panel->appendChild($event_view);
|
||||||
|
$log_panel->appendChild($pager);
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$log_panel,
|
||||||
|
array(
|
||||||
|
'title' => 'Combined Daemon Log',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
18
src/applications/daemon/controller/combined/__init__.php
Normal file
18
src/applications/daemon/controller/combined/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/daemon/view/daemonlogevents');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/event');
|
||||||
|
phutil_require_module('phabricator', 'view/control/pager');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonCombinedLogController.php');
|
|
@ -22,48 +22,26 @@ class PhabricatorDaemonConsoleController extends PhabricatorDaemonController {
|
||||||
$logs = id(new PhabricatorDaemonLog())->loadAllWhere(
|
$logs = id(new PhabricatorDaemonLog())->loadAllWhere(
|
||||||
'1 = 1 ORDER BY id DESC LIMIT 15');
|
'1 = 1 ORDER BY id DESC LIMIT 15');
|
||||||
|
|
||||||
$rows = array();
|
$daemon_table = new PhabricatorDaemonLogListView();
|
||||||
foreach ($logs as $log) {
|
$daemon_table->setDaemonLogs($logs);
|
||||||
$epoch = $log->getDateCreated();
|
|
||||||
|
|
||||||
$rows[] = array(
|
|
||||||
phutil_escape_html($log->getDaemon()),
|
|
||||||
phutil_escape_html($log->getHost()),
|
|
||||||
$log->getPID(),
|
|
||||||
date('M j, Y', $epoch),
|
|
||||||
date('g:i A', $epoch),
|
|
||||||
phutil_render_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => '/daemon/log/'.$log->getID().'/',
|
|
||||||
'class' => 'button small grey',
|
|
||||||
),
|
|
||||||
'View Log'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$daemon_table = new AphrontTableView($rows);
|
|
||||||
$daemon_table->setHeaders(
|
|
||||||
array(
|
|
||||||
'Daemon',
|
|
||||||
'Host',
|
|
||||||
'PID',
|
|
||||||
'Date',
|
|
||||||
'Time',
|
|
||||||
'View',
|
|
||||||
));
|
|
||||||
$daemon_table->setColumnClasses(
|
|
||||||
array(
|
|
||||||
'wide wrap',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'right',
|
|
||||||
'action',
|
|
||||||
));
|
|
||||||
|
|
||||||
$daemon_panel = new AphrontPanelView();
|
$daemon_panel = new AphrontPanelView();
|
||||||
$daemon_panel->setHeader('Recently Launched Daemons');
|
$daemon_panel->setHeader(
|
||||||
|
'Recently Launched Daemons'.
|
||||||
|
' · '.
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/daemon/log/',
|
||||||
|
),
|
||||||
|
'View All Daemons').
|
||||||
|
' · '.
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/daemon/log/combined/',
|
||||||
|
),
|
||||||
|
'View Combined Log'));
|
||||||
$daemon_panel->appendChild($daemon_table);
|
$daemon_panel->appendChild($daemon_table);
|
||||||
|
|
||||||
$tasks = id(new PhabricatorWorkerTask())->loadAllWhere(
|
$tasks = id(new PhabricatorWorkerTask())->loadAllWhere(
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/daemon/view/daemonloglist');
|
||||||
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
||||||
phutil_require_module('phabricator', 'infrastructure/daemon/timeline/storage/cursor');
|
phutil_require_module('phabricator', 'infrastructure/daemon/timeline/storage/cursor');
|
||||||
phutil_require_module('phabricator', 'infrastructure/daemon/workers/storage/task');
|
phutil_require_module('phabricator', 'infrastructure/daemon/workers/storage/task');
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorDaemonLogListController extends PhabricatorDaemonController {
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
$pager = new AphrontPagerView();
|
||||||
|
$pager->setOffset($request->getInt('page'));
|
||||||
|
|
||||||
|
$logs = id(new PhabricatorDaemonLog())->loadAllWhere(
|
||||||
|
'1 = 1 ORDER BY id DESC LIMIT %d, %d',
|
||||||
|
$pager->getOffset(),
|
||||||
|
$pager->getPageSize() + 1);
|
||||||
|
|
||||||
|
$logs = $pager->sliceResults($logs);
|
||||||
|
$pager->setURI($request->getRequestURI(), 'page');
|
||||||
|
|
||||||
|
$daemon_table = new PhabricatorDaemonLogListView();
|
||||||
|
$daemon_table->setDaemonLogs($logs);
|
||||||
|
|
||||||
|
$daemon_panel = new AphrontPanelView();
|
||||||
|
$daemon_panel->setHeader('Launched Daemons');
|
||||||
|
$daemon_panel->appendChild($daemon_table);
|
||||||
|
$daemon_panel->appendChild($pager);
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$daemon_panel,
|
||||||
|
array(
|
||||||
|
'title' => 'All Daemons',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
18
src/applications/daemon/controller/loglist/__init__.php
Normal file
18
src/applications/daemon/controller/loglist/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/daemon/view/daemonloglist');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
||||||
|
phutil_require_module('phabricator', 'view/control/pager');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonLogListController.php');
|
|
@ -34,7 +34,7 @@ class PhabricatorDaemonLogViewController extends PhabricatorDaemonController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$events = id(new PhabricatorDaemonLogEvent())->loadAllWhere(
|
$events = id(new PhabricatorDaemonLogEvent())->loadAllWhere(
|
||||||
'logID = %d ORDER BY id DESC LIMIT 200',
|
'logID = %d ORDER BY id DESC LIMIT 1000',
|
||||||
$log->getID());
|
$log->getID());
|
||||||
|
|
||||||
$content = array();
|
$content = array();
|
||||||
|
@ -72,44 +72,19 @@ class PhabricatorDaemonLogViewController extends PhabricatorDaemonController {
|
||||||
|
|
||||||
$content[] = $panel;
|
$content[] = $panel;
|
||||||
|
|
||||||
$rows = array();
|
$event_view = new PhabricatorDaemonLogEventsView();
|
||||||
foreach ($events as $event) {
|
$event_view->setEvents($events);
|
||||||
$rows[] = array(
|
|
||||||
phutil_escape_html($event->getLogType()),
|
|
||||||
date('M j, Y', $event->getEpoch()),
|
|
||||||
date('g:i:s A', $event->getEpoch()),
|
|
||||||
str_replace("\n", '<br />', phutil_escape_html($event->getMessage())),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$log_table = new AphrontTableView($rows);
|
|
||||||
$log_table->setHeaders(
|
|
||||||
array(
|
|
||||||
'Type',
|
|
||||||
'Date',
|
|
||||||
'Time',
|
|
||||||
'Message',
|
|
||||||
));
|
|
||||||
$log_table->setColumnClasses(
|
|
||||||
array(
|
|
||||||
'',
|
|
||||||
'',
|
|
||||||
'right',
|
|
||||||
'wide wrap',
|
|
||||||
));
|
|
||||||
|
|
||||||
$log_panel = new AphrontPanelView();
|
$log_panel = new AphrontPanelView();
|
||||||
$log_panel->setHeader('Daemon Logs');
|
$log_panel->setHeader('Daemon Logs');
|
||||||
$log_panel->appendChild($log_table);
|
$log_panel->appendChild($event_view);
|
||||||
|
|
||||||
$content[] = $log_panel;
|
$content[] = $log_panel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildStandardPageResponse(
|
||||||
$content,
|
$content,
|
||||||
array(
|
array(
|
||||||
'title' => 'Log',
|
'title' => 'Daemon Log',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,14 @@
|
||||||
|
|
||||||
phutil_require_module('phabricator', 'aphront/response/404');
|
phutil_require_module('phabricator', 'aphront/response/404');
|
||||||
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
phutil_require_module('phabricator', 'applications/daemon/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'applications/daemon/view/daemonlogevents');
|
||||||
phutil_require_module('phabricator', 'infrastructure/daemon/storage/event');
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/event');
|
||||||
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
phutil_require_module('phabricator', 'infrastructure/daemon/storage/log');
|
||||||
phutil_require_module('phabricator', 'view/control/table');
|
|
||||||
phutil_require_module('phabricator', 'view/form/base');
|
phutil_require_module('phabricator', 'view/form/base');
|
||||||
phutil_require_module('phabricator', 'view/form/control/static');
|
phutil_require_module('phabricator', 'view/form/control/static');
|
||||||
phutil_require_module('phabricator', 'view/form/control/textarea');
|
phutil_require_module('phabricator', 'view/form/control/textarea');
|
||||||
phutil_require_module('phabricator', 'view/layout/panel');
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'markup');
|
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class PhabricatorDaemonLogEventsView extends AphrontView {
|
||||||
|
|
||||||
|
private $events;
|
||||||
|
private $combinedLog;
|
||||||
|
|
||||||
|
public function setEvents(array $events) {
|
||||||
|
$this->events = $events;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCombinedLog($is_combined) {
|
||||||
|
$this->combinedLog = $is_combined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() {
|
||||||
|
$rows = array();
|
||||||
|
|
||||||
|
foreach ($this->events as $event) {
|
||||||
|
$row = array(
|
||||||
|
phutil_escape_html($event->getLogType()),
|
||||||
|
date('M j, Y', $event->getEpoch()),
|
||||||
|
date('g:i:s A', $event->getEpoch()),
|
||||||
|
str_replace("\n", '<br />', phutil_escape_html($event->getMessage())),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($this->combinedLog) {
|
||||||
|
array_unshift(
|
||||||
|
$row,
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/daemon/log/'.$event->getLogID().'/',
|
||||||
|
),
|
||||||
|
phutil_escape_html('Daemon '.$event->getLogID())));
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$classes = array(
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'right',
|
||||||
|
'wide wrap',
|
||||||
|
);
|
||||||
|
|
||||||
|
$headers = array(
|
||||||
|
'Type',
|
||||||
|
'Date',
|
||||||
|
'Time',
|
||||||
|
'Message',
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($this->combinedLog) {
|
||||||
|
array_unshift($classes, 'pri');
|
||||||
|
array_unshift($headers, 'Daemon');
|
||||||
|
}
|
||||||
|
|
||||||
|
$log_table = new AphrontTableView($rows);
|
||||||
|
$log_table->setHeaders($headers);
|
||||||
|
$log_table->setColumnClasses($classes);
|
||||||
|
|
||||||
|
return $log_table->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/applications/daemon/view/daemonlogevents/__init__.php
Normal file
15
src/applications/daemon/view/daemonlogevents/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'view/base');
|
||||||
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonLogEventsView.php');
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class PhabricatorDaemonLogListView extends AphrontView {
|
||||||
|
|
||||||
|
private $daemonLogs;
|
||||||
|
|
||||||
|
public function setDaemonLogs(array $daemon_logs) {
|
||||||
|
$this->daemonLogs = $daemon_logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() {
|
||||||
|
$rows = array();
|
||||||
|
|
||||||
|
foreach ($this->daemonLogs as $log) {
|
||||||
|
$epoch = $log->getDateCreated();
|
||||||
|
|
||||||
|
if ($log->getHost() == php_uname('n')) {
|
||||||
|
|
||||||
|
// This will probably fail since apache can't signal the process, but
|
||||||
|
// we can check the error code to figure out if the process exists.
|
||||||
|
$is_running = posix_kill($log->getPID(), 0);
|
||||||
|
if (posix_get_last_error() == 1) {
|
||||||
|
// "Operation Not Permitted", indicates that the PID exists. If it
|
||||||
|
// doesn't, we'll get an error 3 ("No such process") instead.
|
||||||
|
$is_running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_running) {
|
||||||
|
$running = phutil_render_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'style' => 'color: #00cc00',
|
||||||
|
'title' => 'Running',
|
||||||
|
),
|
||||||
|
'•');
|
||||||
|
} else {
|
||||||
|
$running = phutil_render_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'style' => 'color: #cc0000',
|
||||||
|
'title' => 'Not running',
|
||||||
|
),
|
||||||
|
'•');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$running = phutil_render_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'style' => 'color: #888888',
|
||||||
|
'title' => 'Not on this host',
|
||||||
|
),
|
||||||
|
'?');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[] = array(
|
||||||
|
$running,
|
||||||
|
phutil_escape_html($log->getDaemon()),
|
||||||
|
phutil_escape_html($log->getHost()),
|
||||||
|
$log->getPID(),
|
||||||
|
date('M j, Y', $epoch),
|
||||||
|
date('g:i A', $epoch),
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/daemon/log/'.$log->getID().'/',
|
||||||
|
'class' => 'button small grey',
|
||||||
|
),
|
||||||
|
'View Log'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$daemon_table = new AphrontTableView($rows);
|
||||||
|
$daemon_table->setHeaders(
|
||||||
|
array(
|
||||||
|
'',
|
||||||
|
'Daemon',
|
||||||
|
'Host',
|
||||||
|
'PID',
|
||||||
|
'Date',
|
||||||
|
'Time',
|
||||||
|
'View',
|
||||||
|
));
|
||||||
|
$daemon_table->setColumnClasses(
|
||||||
|
array(
|
||||||
|
'',
|
||||||
|
'wide wrap',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
'right',
|
||||||
|
'action',
|
||||||
|
));
|
||||||
|
|
||||||
|
return $daemon_table->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/applications/daemon/view/daemonloglist/__init__.php
Normal file
15
src/applications/daemon/view/daemonloglist/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'view/base');
|
||||||
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorDaemonLogListView.php');
|
|
@ -30,11 +30,7 @@ class PhabricatorFileListController extends PhabricatorFileController {
|
||||||
$pager->getOffset(),
|
$pager->getOffset(),
|
||||||
$pager->getPageSize() + 1);
|
$pager->getPageSize() + 1);
|
||||||
|
|
||||||
if (count($files) > $pager->getPageSize()) {
|
$files = $pager->sliceResults($files);
|
||||||
$files = array_slice($files, 0, $pager->getPageSize(), true);
|
|
||||||
$pager->setHasMorePages(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$pager->setURI($request->getRequestURI(), 'page');
|
$pager->setURI($request->getRequestURI(), 'page');
|
||||||
|
|
||||||
$rows = array();
|
$rows = array();
|
||||||
|
|
|
@ -80,6 +80,32 @@ final class AphrontPagerView extends AphrontView {
|
||||||
return $this->count !== null;
|
return $this->count !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A common paging strategy is to select one extra record and use that to
|
||||||
|
* indicate that there's an additional page (this doesn't give you a
|
||||||
|
* complete page count but is often faster than counting the total number
|
||||||
|
* of items). This method will take a result array, slice it down to the
|
||||||
|
* page size if necessary, and call setHasMorePages() if there are more than
|
||||||
|
* one page of results.
|
||||||
|
*
|
||||||
|
* $results = queryfx_all(
|
||||||
|
* $conn,
|
||||||
|
* 'SELECT ... LIMIT %d, %d',
|
||||||
|
* $pager->getOffset(),
|
||||||
|
* $pager->getPageSize() + 1);
|
||||||
|
* $results = $pager->sliceResults($results);
|
||||||
|
*
|
||||||
|
* @param list Result array.
|
||||||
|
* @return list One page of results.
|
||||||
|
*/
|
||||||
|
public function sliceResults(array $results) {
|
||||||
|
if (count($results) > $this->getPageSize()) {
|
||||||
|
$results = array_slice($results, 0, $this->getPageSize(), true);
|
||||||
|
$this->setHasMorePages(true);
|
||||||
|
}
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
if (!$this->uri) {
|
if (!$this->uri) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
|
Loading…
Reference in a new issue