mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
Unify the local and global view for ./bin/phd status
.
Summary: Ref T4209. Unifies the local (`./bin/phd status`) and global (`./bin/phd status --all`) view into a single table. This generally makes it easy to administer daemons running across multiple hosts. Depends on D9606. Test Plan: ``` > sudo ./bin/phd status ID Host PID Started Daemon Arguments 38 localhost 2282 Jun 18 2014, 7:52:56 AM PhabricatorRepositoryPullLocalDaemon 39 localhost 2289 Jun 18 2014, 7:52:57 AM PhabricatorGarbageCollectorDaemon 40 localhost 2294 Jun 18 2014, 7:52:57 AM PhabricatorTaskmasterDaemon 41 localhost 2314 Jun 18 2014, 7:52:58 AM PhabricatorTaskmasterDaemon 42 localhost 2319 Jun 18 2014, 7:52:59 AM PhabricatorTaskmasterDaemon 43 localhost 2328 Jun 18 2014, 7:53:00 AM PhabricatorTaskmasterDaemon 44 localhost 2354 Jun 18 2014, 7:53:08 AM PhabricatorRepositoryPullLocalDaemon X --not Y ``` Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Maniphest Tasks: T4209 Differential Revision: https://secure.phabricator.com/D9607
This commit is contained in:
parent
b93fe30008
commit
f52fbf6117
6 changed files with 78 additions and 94 deletions
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE {$NAMESPACE}_daemon.daemon_log
|
||||
ADD COLUMN explicitArgv longtext CHARACTER SET utf8
|
||||
COLLATE utf8_bin NOT NULL AFTER argv;
|
|
@ -37,6 +37,7 @@ final class PhabricatorDaemonEventListener extends PhabricatorEventListener {
|
|||
->setPID(getmypid())
|
||||
->setStatus(PhabricatorDaemonLog::STATUS_RUNNING)
|
||||
->setArgv($event->getValue('argv'))
|
||||
->setExplicitArgv($event->getValue('explicitArgv'))
|
||||
->save();
|
||||
|
||||
$this->daemons[$id] = $daemon;
|
||||
|
|
|
@ -7,73 +7,10 @@ final class PhabricatorDaemonManagementStatusWorkflow
|
|||
$this
|
||||
->setName('status')
|
||||
->setSynopsis(pht('Show status of running daemons.'))
|
||||
->setArguments(
|
||||
array(
|
||||
array(
|
||||
'name' => 'all',
|
||||
'help' => pht('Show the status of daemons across all hosts.'),
|
||||
),
|
||||
));
|
||||
->setArguments(array());
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
if ($args->getArg('all')) {
|
||||
return $this->executeGlobal();
|
||||
} else {
|
||||
return $this->executeLocal();
|
||||
}
|
||||
}
|
||||
|
||||
protected function executeLocal() {
|
||||
$console = PhutilConsole::getConsole();
|
||||
$daemons = $this->loadRunningDaemons();
|
||||
|
||||
if (!$daemons) {
|
||||
$console->writeErr(
|
||||
"%s\n",
|
||||
pht('There are no running Phabricator daemons.'));
|
||||
return 1;
|
||||
}
|
||||
|
||||
$status = 0;
|
||||
$table = id(new PhutilConsoleTable())
|
||||
->addColumns(array(
|
||||
'pid' => array(
|
||||
'title' => 'PID',
|
||||
),
|
||||
'started' => array(
|
||||
'title' => 'Started',
|
||||
),
|
||||
'daemon' => array(
|
||||
'title' => 'Daemon',
|
||||
),
|
||||
'argv' => array(
|
||||
'title' => 'Arguments',
|
||||
),
|
||||
));
|
||||
|
||||
foreach ($daemons as $daemon) {
|
||||
$name = $daemon->getName();
|
||||
if (!$daemon->isRunning()) {
|
||||
$daemon->updateStatus(PhabricatorDaemonLog::STATUS_DEAD);
|
||||
$status = 2;
|
||||
$name = '<DEAD> '.$name;
|
||||
}
|
||||
|
||||
$table->addRow(array(
|
||||
'pid' => $daemon->getPID(),
|
||||
'started' => $daemon->getEpochStarted()
|
||||
? date('M j Y, g:i:s A', $daemon->getEpochStarted())
|
||||
: null,
|
||||
'daemon' => $name,
|
||||
'argv' => csprintf('%LR', $daemon->getArgv()),
|
||||
));
|
||||
}
|
||||
|
||||
$table->draw();
|
||||
}
|
||||
|
||||
protected function executeGlobal() {
|
||||
$console = PhutilConsole::getConsole();
|
||||
$daemons = $this->loadAllRunningDaemons();
|
||||
|
||||
|
@ -109,14 +46,40 @@ final class PhabricatorDaemonManagementStatusWorkflow
|
|||
));
|
||||
|
||||
foreach ($daemons as $daemon) {
|
||||
$table->addRow(array(
|
||||
'id' => $daemon->getID(),
|
||||
'host' => $daemon->getHost(),
|
||||
'pid' => $daemon->getPID(),
|
||||
'started' => date('M j Y, g:i:s A', $daemon->getDateCreated()),
|
||||
'daemon' => $daemon->getDaemon(),
|
||||
'argv' => csprintf('%LR', array() /* $daemon->getArgv() */),
|
||||
));
|
||||
if ($daemon instanceof PhabricatorDaemonLog) {
|
||||
$table->addRow(array(
|
||||
'id' => $daemon->getID(),
|
||||
'host' => $daemon->getHost(),
|
||||
'pid' => $daemon->getPID(),
|
||||
'started' => date('M j Y, g:i:s A', $daemon->getDateCreated()),
|
||||
'daemon' => $daemon->getDaemon(),
|
||||
'argv' => csprintf('%LR', $daemon->getExplicitArgv()),
|
||||
));
|
||||
} else if ($daemon instanceof PhabricatorDaemonReference) {
|
||||
$name = $daemon->getName();
|
||||
if (!$daemon->isRunning()) {
|
||||
$daemon->updateStatus(PhabricatorDaemonLog::STATUS_DEAD);
|
||||
$status = 2;
|
||||
$name = '<DEAD> '.$name;
|
||||
}
|
||||
|
||||
$daemon_log = $daemon->getDaemonLog();
|
||||
$id = null;
|
||||
if ($daemon_log) {
|
||||
$id = $daemon_log->getID();
|
||||
}
|
||||
|
||||
$table->addRow(array(
|
||||
'id' => $id,
|
||||
'host' => 'localhost',
|
||||
'pid' => $daemon->getPID(),
|
||||
'started' => $daemon->getEpochStarted()
|
||||
? date('M j Y, g:i:s A', $daemon->getEpochStarted())
|
||||
: null,
|
||||
'daemon' => $name,
|
||||
'argv' => csprintf('%LR', $daemon->getArgv()),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$table->draw();
|
||||
|
|
|
@ -36,35 +36,38 @@ abstract class PhabricatorDaemonManagementWorkflow
|
|||
}
|
||||
|
||||
protected final function loadRunningDaemons() {
|
||||
$results = array();
|
||||
$daemons = array();
|
||||
|
||||
$pid_dir = $this->getPIDDirectory();
|
||||
$pid_files = Filesystem::listDirectory($pid_dir);
|
||||
if (!$pid_files) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
foreach ($pid_files as $pid_file) {
|
||||
$pid_data = Filesystem::readFile($pid_dir.'/'.$pid_file);
|
||||
$dict = json_decode($pid_data, true);
|
||||
if (!is_array($dict)) {
|
||||
// Just return a hanging reference, since control code needs to be
|
||||
// robust against unusual system states.
|
||||
$dict = array();
|
||||
}
|
||||
$ref = PhabricatorDaemonReference::newFromDictionary($dict);
|
||||
$ref->setPIDFile($pid_dir.'/'.$pid_file);
|
||||
$results[] = $ref;
|
||||
$daemons[] = PhabricatorDaemonReference::newFromFile(
|
||||
$pid_dir.'/'.$pid_file);
|
||||
}
|
||||
|
||||
return $results;
|
||||
return $daemons;
|
||||
}
|
||||
|
||||
protected final function loadAllRunningDaemons() {
|
||||
return id(new PhabricatorDaemonLogQuery())
|
||||
$local_daemons = $this->loadRunningDaemons();
|
||||
|
||||
$local_ids = array();
|
||||
foreach ($local_daemons as $daemon) {
|
||||
$daemon_log = $daemon->getDaemonLog();
|
||||
|
||||
if ($daemon_log) {
|
||||
$local_ids[] = $daemon_log->getID();
|
||||
}
|
||||
}
|
||||
|
||||
$remote_daemons = id(new PhabricatorDaemonLogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withoutIDs($local_ids)
|
||||
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||
->execute();
|
||||
|
||||
return array_merge($local_daemons, $remote_daemons);
|
||||
}
|
||||
|
||||
private function findDaemonClass($substring) {
|
||||
|
@ -280,7 +283,6 @@ abstract class PhabricatorDaemonManagementWorkflow
|
|||
}
|
||||
|
||||
$console->writeErr(pht('Done.')."\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,14 @@ final class PhabricatorDaemonLog extends PhabricatorDaemonDAO
|
|||
protected $host;
|
||||
protected $pid;
|
||||
protected $argv;
|
||||
protected $explicitArgv;
|
||||
protected $status;
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_SERIALIZATION => array(
|
||||
'argv' => self::SERIALIZATION_JSON,
|
||||
'explicitArgv' => self::SERIALIZATION_JSON,
|
||||
),
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,14 @@ final class PhabricatorDaemonReference {
|
|||
|
||||
private $daemonLog;
|
||||
|
||||
public static function newFromFile($path) {
|
||||
$pid_data = Filesystem::readFile($path);
|
||||
$dict = phutil_json_decode($pid_data);
|
||||
$ref = self::newFromDictionary($dict);
|
||||
$ref->pidFile = $path;
|
||||
return $ref;
|
||||
}
|
||||
|
||||
public static function newFromDictionary(array $dict) {
|
||||
$ref = new PhabricatorDaemonReference();
|
||||
|
||||
|
@ -18,6 +26,12 @@ final class PhabricatorDaemonReference {
|
|||
$ref->pid = idx($dict, 'pid');
|
||||
$ref->start = idx($dict, 'start');
|
||||
|
||||
$ref->daemonLog = id(new PhabricatorDaemonLog())->loadOneWhere(
|
||||
'daemon = %s AND pid = %d AND dateCreated = %d',
|
||||
$ref->name,
|
||||
$ref->pid,
|
||||
$ref->start);
|
||||
|
||||
return $ref;
|
||||
}
|
||||
|
||||
|
@ -66,15 +80,14 @@ final class PhabricatorDaemonReference {
|
|||
return $this->start;
|
||||
}
|
||||
|
||||
public function setPIDFile($pid_file) {
|
||||
$this->pidFile = $pid_file;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPIDFile() {
|
||||
return $this->pidFile;
|
||||
}
|
||||
|
||||
public function getDaemonLog() {
|
||||
return $this->daemonLog;
|
||||
}
|
||||
|
||||
public function isRunning() {
|
||||
return self::isProcessRunning($this->getPID());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue