diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php --- a/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php @@ -22,12 +22,22 @@ } $status = 0; - printf( - "%-5s\t%-24s\t%-50s%s\n", - 'PID', - 'Started', - 'Daemon', - 'Arguments'); + $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()) { @@ -35,18 +45,67 @@ $status = 2; $name = ' '.$name; } - printf( - "%5s\t%-24s\t%-50s%s\n", - $daemon->getPID(), - $daemon->getEpochStarted() + + $table->addRow(array( + 'pid' => $daemon->getPID(), + 'started' => $daemon->getEpochStarted() ? date('M j Y, g:i:s A', $daemon->getEpochStarted()) : null, - $name, - csprintf('%LR', $daemon->getArgv())); + 'daemon' => $name, + 'argv' => csprintf('%LR', $daemon->getArgv()), + )); } - return $status; + $table->draw(); } + protected function executeGlobal() { + $console = PhutilConsole::getConsole(); + $daemons = $this->loadAllRunningDaemons(); + + if (!$daemons) { + $console->writeErr( + "%s\n", + pht('There are no running Phabricator daemons.')); + return 1; + } + + $status = 0; + + $table = id(new PhutilConsoleTable()) + ->addColumns(array( + 'id' => array( + 'title' => 'ID', + ), + 'host' => array( + 'title' => 'Host', + ), + 'pid' => array( + 'title' => 'PID', + ), + 'started' => array( + 'title' => 'Started', + ), + 'daemon' => array( + 'title' => 'Daemon', + ), + 'argv' => array( + 'title' => 'Arguments', + ), + )); + + 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() */), + )); + } + + $table->draw(); + } } diff --git a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php --- a/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php +++ b/src/applications/daemon/management/PhabricatorDaemonManagementWorkflow.php @@ -3,7 +3,7 @@ abstract class PhabricatorDaemonManagementWorkflow extends PhabricatorManagementWorkflow { - protected function loadAvailableDaemonClasses() { + protected final function loadAvailableDaemonClasses() { $loader = new PhutilSymbolLoader(); return $loader ->setAncestorClass('PhutilDaemon') @@ -11,12 +11,12 @@ ->selectSymbolsWithoutLoading(); } - public function getPIDDirectory() { + protected final function getPIDDirectory() { $path = PhabricatorEnv::getEnvConfig('phd.pid-directory'); return $this->getControlDirectory($path); } - public function getLogDirectory() { + protected final function getLogDirectory() { $path = PhabricatorEnv::getEnvConfig('phd.log-directory'); return $this->getControlDirectory($path); } @@ -35,8 +35,9 @@ return $path; } - public function loadRunningDaemons() { + protected final function loadRunningDaemons() { $results = array(); + $ids = array(); $pid_dir = $this->getPIDDirectory(); $pid_files = Filesystem::listDirectory($pid_dir); @@ -45,19 +46,17 @@ } 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; + $results[] = PhabricatorDaemonReference::newFromDictionary( + $pid_dir.'/'.$pid_file); + $ids[] = $ref->getDaemonLog()->getID(); } - return $results; + $other = id(new PhabricatorDaemonLogQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) + ->execute(); + + } private function findDaemonClass($substring) { @@ -93,8 +92,7 @@ return head($match); } - - protected function launchDaemon($class, array $argv, $debug) { + protected final function launchDaemon($class, array $argv, $debug) { $daemon = $this->findDaemonClass($class); $console = PhutilConsole::getConsole(); @@ -212,7 +210,7 @@ } } - protected function willLaunchDaemons() { + protected final function willLaunchDaemons() { $console = PhutilConsole::getConsole(); $console->writeErr(pht('Preparing to launch daemons.')."\n"); @@ -224,7 +222,7 @@ /* -( Commands )----------------------------------------------------------- */ - protected function executeStartCommand($keep_leases = false) { + protected final function executeStartCommand($keep_leases = false) { $console = PhutilConsole::getConsole(); $running = $this->loadRunningDaemons(); @@ -278,8 +276,7 @@ return 0; } - - protected function executeStopCommand(array $pids) { + protected final function executeStopCommand(array $pids) { $console = PhutilConsole::getConsole(); $daemons = $this->loadRunningDaemons(); diff --git a/src/infrastructure/daemon/control/PhabricatorDaemonReference.php b/src/infrastructure/daemon/control/PhabricatorDaemonReference.php --- a/src/infrastructure/daemon/control/PhabricatorDaemonReference.php +++ b/src/infrastructure/daemon/control/PhabricatorDaemonReference.php @@ -10,6 +10,19 @@ private $daemonLog; + public static function newFromFile($path) { + $pid_data = Filesystem::readFile($path); + $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 = self::newFromDictionary($dict); + $ref->pidFile = $path; + return $ref; + } + public static function newFromDictionary(array $dict) { $ref = new PhabricatorDaemonReference(); @@ -18,6 +31,12 @@ $ref->pid = idx($dict, 'pid'); $ref->start = idx($dict, 'start'); + $this->daemonLog = id(new PhabricatorDaemonLog())->loadOneWhere( + 'daemon = %s AND pid = %d AND dateCreated = %d', + $this->name, + $this->pid, + $this->start); + return $ref; } @@ -66,15 +85,14 @@ 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()); }