From a38a18f0fdd1d47464cf105e329b3c08a6873fbb Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sat, 26 Oct 2013 12:07:06 +0100 Subject: [PATCH 1/8] Adding psr3 logging interface and monolog to the project's composer.json. --- composer.json | 4 +- composer.lock | 106 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 9e3ff52a..e6fac6cb 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,9 @@ "ircmaxell/password-compat": "1.*", "swiftmailer/swiftmailer" : "5.0.*", "symfony/yaml" : "2.*", - "symfony/console" : "2.*" + "symfony/console" : "2.*", + "psr/log": "1.0.0", + "monolog/monolog": "1.6.0" }, "suggest": { diff --git a/composer.lock b/composer.lock index 4921df46..43452ea3 100644 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "04cca0ac809838a65555d04534cc95ae", + "hash": "534baabecc11275d5cc7f375eecf738d", "packages": [ { "name": "block8/b8framework", @@ -91,6 +91,106 @@ ], "time": "2013-04-30 19:58:08" }, + { + "name": "monolog/monolog", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "f72392d0e6eb855118f5a84e89ac2d257c704abd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f72392d0e6eb855118f5a84e89ac2d257c704abd", + "reference": "f72392d0e6eb855118f5a84e89ac2d257c704abd", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "require-dev": { + "doctrine/couchdb": "dev-master", + "mlehner/gelf-php": "1.0.*", + "raven/raven": "0.5.*" + }, + "suggest": { + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server", + "raven/raven": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Monolog": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be", + "role": "Developer" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2013-07-28 22:38:30" + }, + { + "name": "psr/log", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", + "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Psr\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2012-12-21 11:40:51" + }, { "name": "swiftmailer/swiftmailer", "version": "v5.0.2", @@ -142,7 +242,7 @@ }, { "name": "symfony/console", - "version": "v2.3.5", + "version": "v2.3.6", "target-dir": "Symfony/Component/Console", "source": { "type": "git", @@ -195,7 +295,7 @@ }, { "name": "symfony/yaml", - "version": "v2.3.5", + "version": "v2.3.6", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", From 1989203635979804a72a22f9e7506b195a11a28b Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sat, 26 Oct 2013 16:11:46 +0100 Subject: [PATCH 2/8] Adding two custom log handlers. One to link the logs to symphony console output to the logging and another to record build specific information in the DB. --- PHPCI/Command/RunCommand.php | 37 ++++++++++++++++++++++-------- PHPCI/Helper/BuildDBLogHandler.php | 33 ++++++++++++++++++++++++++ PHPCI/Helper/OutputLogHandler.php | 32 ++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 PHPCI/Helper/BuildDBLogHandler.php create mode 100644 PHPCI/Helper/OutputLogHandler.php diff --git a/PHPCI/Command/RunCommand.php b/PHPCI/Command/RunCommand.php index dc8e21d2..26ef6c1e 100644 --- a/PHPCI/Command/RunCommand.php +++ b/PHPCI/Command/RunCommand.php @@ -9,6 +9,10 @@ namespace PHPCI\Command; +use Monolog\Logger; +use PHPCI\Helper\BuildDBLogHandler; +use PHPCI\Helper\OutputLogHandler; +use Psr\Log\LoggerAwareInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -26,6 +30,11 @@ use PHPCI\BuildFactory; */ class RunCommand extends Command { + /** + * @var OutputInterface + */ + protected $output; + protected function configure() { $this @@ -40,26 +49,36 @@ class RunCommand extends Command { $this->output = $output; + $logger = new Logger("BuildLog"); + $store = Factory::getStore('Build'); $result = $store->getByStatus(0); $builds = 0; + // For verbose mode we want to output all informational and above + // messages to the symphony output interface. + if ($input->getOption('verbose')) { + $logger->pushHandler( + new OutputLogHandler($this->output, Logger::INFO) + ); + } + foreach ($result['items'] as $build) { $builds++; $build = BuildFactory::getBuild($build); - if ($input->getOption('verbose')) { - $builder = new Builder($build, function ($log) { - $this->output->writeln($log); - }); - } else { - $builder = new Builder($build, function () { - // Empty stub function. - }); - } + // Logging relevant to this build should be stored + // against the build itself. + $buildDbLog = new BuildDBLogHandler($build, Logger::INFO); + $logger->pushHandler($buildDbLog); + $builder = new Builder($build, $logger); $builder->execute(); + + // After execution we no longer want to record the information + // back to this specific build so the handler should be removed. + $logger->popHandler($buildDbLog); } return $builds; diff --git a/PHPCI/Helper/BuildDBLogHandler.php b/PHPCI/Helper/BuildDBLogHandler.php new file mode 100644 index 00000000..c886767a --- /dev/null +++ b/PHPCI/Helper/BuildDBLogHandler.php @@ -0,0 +1,33 @@ +build = $build; + // We want to add to any existing saved log information. + $this->logValue = $build->getLog(); + } + + protected function write(array $record) { + $this->logValue .= (string) $record['formatted']; + $this->build->setLog($this->logValue); + } +} \ No newline at end of file diff --git a/PHPCI/Helper/OutputLogHandler.php b/PHPCI/Helper/OutputLogHandler.php new file mode 100644 index 00000000..7dd46d20 --- /dev/null +++ b/PHPCI/Helper/OutputLogHandler.php @@ -0,0 +1,32 @@ +output = $output; + } + + + protected function write(array $record) + { + $this->output->writeln((string) $record['formatted']); + } + + +} \ No newline at end of file From 8c88581021736b5a3fc7ea4c056207554a8beb76 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sat, 26 Oct 2013 16:15:29 +0100 Subject: [PATCH 3/8] Modified the builder so that it expects to have a psr3 compliant logger attached. --- PHPCI/BuildFactory.php | 2 +- PHPCI/Builder.php | 79 +++++++++++++++++++++++++----------------- PHPCI/Plugin/Atoum.php | 4 +-- 3 files changed, 51 insertions(+), 34 deletions(-) diff --git a/PHPCI/BuildFactory.php b/PHPCI/BuildFactory.php index e4628434..0dd53058 100644 --- a/PHPCI/BuildFactory.php +++ b/PHPCI/BuildFactory.php @@ -22,7 +22,7 @@ class BuildFactory { /** * Takes a generic build and returns a type-specific build model. - * @return PHPCI\Model\Build\LocalBuild|PHPCI\Model\Build\GithubBuild|PHPCI\Model\Build\BitbucketBuild + * @return \PHPCI\Model\Build\LocalBuild|\PHPCI\Model\Build\GithubBuild|\PHPCI\Model\Build\BitbucketBuild */ public static function getBuild(Build $base) { diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 6fa20be0..14a82f18 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -12,12 +12,15 @@ namespace PHPCI; use PHPCI\Model\Build; use b8\Store; use b8\Config; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; /** * PHPCI Build Runner * @author Dan Cryer */ -class Builder +class Builder implements LoggerAwareInterface { /** * @var string @@ -44,11 +47,6 @@ class Builder */ protected $success = true; - /** - * @var string - */ - protected $log = ''; - /** * @var bool */ @@ -59,10 +57,10 @@ class Builder */ protected $build; - /** - * @var callable - */ - protected $logCallback; + /** + * @var LoggerInterface + */ + protected $logger; /** * @var array @@ -94,14 +92,16 @@ class Builder /** * Set up the builder. - * @param \PHPCI\Model\Build - * @param callable + * @param \PHPCI\Model\Build $build + * @param LoggerInterface $logger */ - public function __construct(Build $build, \Closure $logCallback) + public function __construct(Build $build, $logger = null) { + if ($logger) { + $this->setLogger($logger); + } $this->build = $build; $this->store = Store\Factory::getStore('Build'); - $this->logCallback = $logCallback; } /** @@ -164,7 +164,6 @@ class Builder // Run the core plugin stages: foreach (array('setup', 'test', 'complete') as $stage) { $this->executePlugins($stage); - $this->log(''); } // Failed build? Execute failure plugins and then mark the build as failed. @@ -192,7 +191,6 @@ class Builder // Update the build in the database, ping any external services, etc. $this->build->sendStatusPostback(); $this->build->setFinished(new \DateTime()); - $this->build->setLog($this->log); $this->store->save($this->build); } @@ -204,14 +202,14 @@ class Builder $command = call_user_func_array('sprintf', func_get_args()); if (!$this->quiet) { - $this->log('Executing: ' . $command, ' '); + $this->log('Executing: ' . $command); } $status = 0; exec($command, $this->lastOutput, $status); if (!empty($this->lastOutput) && ($this->verbose || $status != 0)) { - $this->log($this->lastOutput, ' '); + $this->log($this->lastOutput); } @@ -232,24 +230,25 @@ class Builder return implode(PHP_EOL, $this->lastOutput); } - /** - * Add an entry to the build log. - * @param string|string[] - * @param string - */ - public function log($message, $prefix = '') + /** + * Add an entry to the build log. + * @param string|string[] $message + * @param string $level + * @param mixed[] $context + */ + public function log($message, $level = LogLevel::INFO, $context = array()) { + // Skip if no logger has been loaded. + if (!$this->logger) { + return; + } + if (!is_array($message)) { $message = array($message); } - foreach ($message as $item) { - call_user_func_array($this->logCallback, array($prefix . $item)); - $this->log .= $prefix . $item . PHP_EOL; + $this->logger->log($level, $item, $context); } - - $this->build->setLog($this->log); - $this->store->save($this->build); } /** @@ -354,7 +353,6 @@ class Builder } foreach ($this->config[$stage] as $plugin => $options) { - $this->log(''); $this->log('RUNNING PLUGIN: ' . $plugin); // Is this plugin allowed to fail? @@ -445,4 +443,23 @@ class Builder return null; } + + /** + * Sets a logger instance on the object + * + * @param LoggerInterface $logger + * @return null + */ + public function setLogger(LoggerInterface $logger) { + $this->logger = $logger; + } + + /** + * returns the logger attached to this builder. + * + * @return LoggerInterface + */ + public function getLogger() { + return $this->logger; + } } diff --git a/PHPCI/Plugin/Atoum.php b/PHPCI/Plugin/Atoum.php index 7a837b0a..c6e2f2e6 100644 --- a/PHPCI/Plugin/Atoum.php +++ b/PHPCI/Plugin/Atoum.php @@ -56,11 +56,11 @@ class Atoum implements \PHPCI\Plugin if (count(preg_grep("/Success \(/", $output)) == 0) { $status = false; - $this->phpci->log($output, ' '); + $this->phpci->log($output); } if (count($output) == 0) { $status = false; - $this->phpci->log("No test have been performed!", ' '); + $this->phpci->log("No test have been performed!"); } return $status; From b943c07f8725083aac0de7df5d713346e841a965 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sat, 26 Oct 2013 16:25:34 +0100 Subject: [PATCH 4/8] Fixing some formatting issues --- PHPCI/Builder.php | 223 +++++++++++++++-------------- PHPCI/Helper/BuildDBLogHandler.php | 38 ++--- PHPCI/Helper/OutputLogHandler.php | 31 ++-- 3 files changed, 153 insertions(+), 139 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 14a82f18..8533816a 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -1,11 +1,11 @@ -*/ + * PHPCI Build Runner + * @author Dan Cryer + */ class Builder implements LoggerAwareInterface { /** - * @var string - */ + * @var string + */ public $buildPath; /** - * @var string[] - */ - public $ignore = array(); + * @var string[] + */ + public $ignore = array(); /** - * @var string - */ + * @var string + */ protected $ciDir; /** - * @var string - */ + * @var string + */ protected $directory; /** - * @var bool - */ - protected $success = true; + * @var bool + */ + protected $success = true; /** - * @var bool - */ - protected $verbose = true; + * @var bool + */ + protected $verbose = true; /** - * @var \PHPCI\Model\Build - */ + * @var \PHPCI\Model\Build + */ protected $build; - /** - * @var LoggerInterface - */ - protected $logger; + /** + * @var LoggerInterface + */ + protected $logger; /** - * @var array - */ + * @var array + */ protected $config; /** @@ -73,7 +73,7 @@ class Builder implements LoggerAwareInterface protected $lastOutput; /** - * An array of key => value pairs that will be used for + * An array of key => value pairs that will be used for * interpolation and environment variables * @var array * @see setInterpolationVars() @@ -91,32 +91,32 @@ class Builder implements LoggerAwareInterface public $quiet = false; /** - * Set up the builder. - * @param \PHPCI\Model\Build $build - * @param LoggerInterface $logger - */ + * Set up the builder. + * @param \PHPCI\Model\Build $build + * @param LoggerInterface $logger + */ public function __construct(Build $build, $logger = null) { - if ($logger) { - $this->setLogger($logger); - } + if ($logger) { + $this->setLogger($logger); + } $this->build = $build; $this->store = Store\Factory::getStore('Build'); } /** - * Set the config array, as read from phpci.yml - * @param array - */ + * Set the config array, as read from phpci.yml + * @param array + */ public function setConfigArray(array $config) { $this->config = $config; } /** - * Access a variable from the phpci.yml file. - * @param string - */ + * Access a variable from the phpci.yml file. + * @param string + */ public function getConfig($key) { $rtn = null; @@ -147,8 +147,8 @@ class Builder implements LoggerAwareInterface } /** - * Run the active build. - */ + * Run the active build. + */ public function execute() { // Update the build in the database, ping any external services. @@ -183,7 +183,7 @@ class Builder implements LoggerAwareInterface $this->logFailure($ex->getMessage()); $this->build->setStatus(3); } - + // Clean up: $this->log('Removing build.'); shell_exec(sprintf('rm -Rf "%s"', $this->buildPath)); @@ -195,8 +195,8 @@ class Builder implements LoggerAwareInterface } /** - * Used by this class, and plugins, to execute shell commands. - */ + * Used by this class, and plugins, to execute shell commands. + */ public function executeCommand() { $command = call_user_func_array('sprintf', func_get_args()); @@ -230,45 +230,45 @@ class Builder implements LoggerAwareInterface return implode(PHP_EOL, $this->lastOutput); } - /** - * Add an entry to the build log. - * @param string|string[] $message - * @param string $level - * @param mixed[] $context - */ + /** + * Add an entry to the build log. + * @param string|string[] $message + * @param string $level + * @param mixed[] $context + */ public function log($message, $level = LogLevel::INFO, $context = array()) { - // Skip if no logger has been loaded. - if (!$this->logger) { - return; - } + // Skip if no logger has been loaded. + if (!$this->logger) { + return; + } if (!is_array($message)) { $message = array($message); } foreach ($message as $item) { - $this->logger->log($level, $item, $context); + $this->logger->log($level, $item, $context); } } /** - * Add a success-coloured message to the log. - * @param string - */ + * Add a success-coloured message to the log. + * @param string + */ public function logSuccess($message) { $this->log("\033[0;32m" . $message . "\033[0m"); } /** - * Add a failure-coloured message to the log. - * @param string - */ + * Add a failure-coloured message to the log. + * @param string + */ public function logFailure($message) { $this->log("\033[0;31m" . $message . "\033[0m"); } - + /** * Replace every occurance of the interpolation vars in the given string * Example: "This is build %PHPCI_BUILD%" => "This is build 182" @@ -283,7 +283,7 @@ class Builder implements LoggerAwareInterface } /** - * Sets the variables that will be used for interpolation. This must be run + * Sets the variables that will be used for interpolation. This must be run * from setupBuild() because prior to that, we don't know the buildPath */ protected function setInterpolationVars() @@ -293,9 +293,11 @@ class Builder implements LoggerAwareInterface $this->interpolation_vars['%COMMIT%'] = $this->build->getCommitId(); $this->interpolation_vars['%PROJECT%'] = $this->build->getProjectId(); $this->interpolation_vars['%BUILD%'] = $this->build->getId(); - $this->interpolation_vars['%PROJECT_TITLE%'] = $this->getBuildProjectTitle(); + $this->interpolation_vars['%PROJECT_TITLE%'] = $this->getBuildProjectTitle( + ); $this->interpolation_vars['%BUILD_PATH%'] = $this->buildPath; - $this->interpolation_vars['%BUILD_URI%'] = PHPCI_URL . "build/view/" . $this->build->getId(); + $this->interpolation_vars['%BUILD_URI%'] = PHPCI_URL . "build/view/" . $this->build->getId( + ); $this->interpolation_vars['%PHPCI_COMMIT%'] = $this->interpolation_vars['%COMMIT%']; $this->interpolation_vars['%PHPCI_PROJECT%'] = $this->interpolation_vars['%PROJECT%']; $this->interpolation_vars['%PHPCI_BUILD%'] = $this->interpolation_vars['%BUILD%']; @@ -304,25 +306,28 @@ class Builder implements LoggerAwareInterface $this->interpolation_vars['%PHPCI_BUILD_URI%'] = $this->interpolation_vars['%BUILD_URI%']; putenv('PHPCI=1'); - putenv('PHPCI_COMMIT='.$this->interpolation_vars['%COMMIT%']); - putenv('PHPCI_PROJECT='.$this->interpolation_vars['%PROJECT%']); - putenv('PHPCI_BUILD='.$this->interpolation_vars['%BUILD%']); - putenv('PHPCI_PROJECT_TITLE='.$this->interpolation_vars['%PROJECT_TITLE%']); - putenv('PHPCI_BUILD_PATH='.$this->interpolation_vars['%BUILD_PATH%']); - putenv('PHPCI_BUILD_URI='.$this->interpolation_vars['%BUILD_URI%']); + putenv('PHPCI_COMMIT=' . $this->interpolation_vars['%COMMIT%']); + putenv('PHPCI_PROJECT=' . $this->interpolation_vars['%PROJECT%']); + putenv('PHPCI_BUILD=' . $this->interpolation_vars['%BUILD%']); + putenv( + 'PHPCI_PROJECT_TITLE=' . $this->interpolation_vars['%PROJECT_TITLE%'] + ); + putenv('PHPCI_BUILD_PATH=' . $this->interpolation_vars['%BUILD_PATH%']); + putenv('PHPCI_BUILD_URI=' . $this->interpolation_vars['%BUILD_URI%']); } - + /** - * Set up a working copy of the project for building. - */ + * Set up a working copy of the project for building. + */ protected function setupBuild() { - $buildId = 'project' . $this->build->getProject()->getId() . '-build' . $this->build->getId(); - $this->ciDir = dirname(__FILE__) . '/../'; - $this->buildPath = $this->ciDir . 'build/' . $buildId . '/'; - + $buildId = 'project' . $this->build->getProject()->getId( + ) . '-build' . $this->build->getId(); + $this->ciDir = dirname(__FILE__) . '/../'; + $this->buildPath = $this->ciDir . 'build/' . $buildId . '/'; + $this->setInterpolationVars(); - + // Create a working copy of the project: if (!$this->build->createWorkingCopy($this, $this->buildPath)) { throw new \Exception('Could not create a working copy.'); @@ -343,12 +348,16 @@ class Builder implements LoggerAwareInterface } /** - * Execute a the appropriate set of plugins for a given build stage. - */ + * Execute a the appropriate set of plugins for a given build stage. + */ protected function executePlugins($stage) { // Ignore any stages for which we don't have plugins set: - if (!array_key_exists($stage, $this->config) || !is_array($this->config[$stage])) { + if (!array_key_exists( + $stage, + $this->config + ) || !is_array($this->config[$stage]) + ) { return; } @@ -444,22 +453,24 @@ class Builder implements LoggerAwareInterface return null; } - /** - * Sets a logger instance on the object - * - * @param LoggerInterface $logger - * @return null - */ - public function setLogger(LoggerInterface $logger) { - $this->logger = $logger; - } + /** + * Sets a logger instance on the object + * + * @param LoggerInterface $logger + * @return null + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } - /** - * returns the logger attached to this builder. - * - * @return LoggerInterface - */ - public function getLogger() { - return $this->logger; - } + /** + * returns the logger attached to this builder. + * + * @return LoggerInterface + */ + public function getLogger() + { + return $this->logger; + } } diff --git a/PHPCI/Helper/BuildDBLogHandler.php b/PHPCI/Helper/BuildDBLogHandler.php index c886767a..6ae34379 100644 --- a/PHPCI/Helper/BuildDBLogHandler.php +++ b/PHPCI/Helper/BuildDBLogHandler.php @@ -9,25 +9,27 @@ use PHPCI\Model\Build; class BuildDBLogHandler extends AbstractProcessingHandler { - /** - * @var Build - */ - protected $build; + /** + * @var Build + */ + protected $build; - protected $logValue; + protected $logValue; - function __construct(Build $build, - $level = LogLevel::INFO, - $bubble = true) - { - parent::__construct($level, $bubble); - $this->build = $build; - // We want to add to any existing saved log information. - $this->logValue = $build->getLog(); - } + function __construct( + Build $build, + $level = LogLevel::INFO, + $bubble = true + ) { + parent::__construct($level, $bubble); + $this->build = $build; + // We want to add to any existing saved log information. + $this->logValue = $build->getLog(); + } - protected function write(array $record) { - $this->logValue .= (string) $record['formatted']; - $this->build->setLog($this->logValue); - } + protected function write(array $record) + { + $this->logValue .= (string)$record['formatted']; + $this->build->setLog($this->logValue); + } } \ No newline at end of file diff --git a/PHPCI/Helper/OutputLogHandler.php b/PHPCI/Helper/OutputLogHandler.php index 7dd46d20..993f1c33 100644 --- a/PHPCI/Helper/OutputLogHandler.php +++ b/PHPCI/Helper/OutputLogHandler.php @@ -9,24 +9,25 @@ use Symfony\Component\Console\Output\OutputInterface; class OutputLogHandler extends AbstractProcessingHandler { - /** - * @var OutputInterface - */ - protected $output; + /** + * @var OutputInterface + */ + protected $output; - function __construct(OutputInterface $output, - $level = LogLevel::INFO, - $bubble = true) - { - parent::__construct($level, $bubble); - $this->output = $output; - } + function __construct( + OutputInterface $output, + $level = LogLevel::INFO, + $bubble = true + ) { + parent::__construct($level, $bubble); + $this->output = $output; + } - protected function write(array $record) - { - $this->output->writeln((string) $record['formatted']); - } + protected function write(array $record) + { + $this->output->writeln((string)$record['formatted']); + } } \ No newline at end of file From fc2434b65d3e67e7952919edecc7bc0bbf11ac08 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sun, 27 Oct 2013 12:51:49 +0000 Subject: [PATCH 5/8] Exceptions can now be passed in to the failure logging function. --- PHPCI/Builder.php | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 8533816a..2480dbe4 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -180,7 +180,7 @@ class Builder implements LoggerAwareInterface } } catch (\Exception $ex) { - $this->logFailure($ex->getMessage()); + $this->logFailure($ex->getMessage(), $ex); $this->build->setStatus(3); } @@ -262,11 +262,24 @@ class Builder implements LoggerAwareInterface /** * Add a failure-coloured message to the log. - * @param string + * @param string $message + * @param \Exception $exception The exception that caused the error. */ - public function logFailure($message) + public function logFailure($message, \Exception $exception = null) { - $this->log("\033[0;31m" . $message . "\033[0m"); + $context = array(); + + // The psr3 log interface stipulates that exceptions should be passed + // as the exception key in the context array. + if ($exception) { + $context['exception'] = $exception; + } + + $this->log( + "\033[0;31m" . $message . "\033[0m", + LogLevel::ERROR, + $context + ); } /** @@ -399,7 +412,7 @@ class Builder implements LoggerAwareInterface $class = 'PHPCI\\Plugin\\' . str_replace(' ', '', $class); if (!class_exists($class)) { - $this->logFailure('Plugin does not exist: ' . $plugin); + $this->logFailure('Plugin does not exist: ' . $plugin, $ex); return false; } @@ -413,7 +426,7 @@ class Builder implements LoggerAwareInterface $rtn = false; } } catch (\Exception $ex) { - $this->logFailure('EXCEPTION: ' . $ex->getMessage()); + $this->logFailure('EXCEPTION: ' . $ex->getMessage(), $ex); $rtn = false; } From e44c7b90d614be2177f7c788232a831b7ccfee5e Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sun, 27 Oct 2013 14:21:08 +0000 Subject: [PATCH 6/8] All build logs calls now pass the build through as part of the context so this gets recorded in the log message. --- PHPCI/Builder.php | 5 ++++ PHPCI/Helper/LoggedBuildContextTidier.php | 31 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 PHPCI/Helper/LoggedBuildContextTidier.php diff --git a/PHPCI/Builder.php b/PHPCI/Builder.php index 2480dbe4..11e46082 100644 --- a/PHPCI/Builder.php +++ b/PHPCI/Builder.php @@ -246,6 +246,11 @@ class Builder implements LoggerAwareInterface if (!is_array($message)) { $message = array($message); } + + // The build is added to the context so the logger can use + // details from it if required. + $context['build'] = $this; + foreach ($message as $item) { $this->logger->log($level, $item, $context); } diff --git a/PHPCI/Helper/LoggedBuildContextTidier.php b/PHPCI/Helper/LoggedBuildContextTidier.php new file mode 100644 index 00000000..2a8a5e72 --- /dev/null +++ b/PHPCI/Helper/LoggedBuildContextTidier.php @@ -0,0 +1,31 @@ +tidyLoggedBuildContext(func_get_arg(0)); + } + + /** + * Removes the build object from the logged record and adds the ID as + * this is more useful to display. + * + * @param array $logRecord + * @return array + */ + protected function tidyLoggedBuildContext(array $logRecord) + { + if (isset($logRecord['context']['build'])) { + $build = $logRecord['context']['build']; + if ($build instanceof Build) { + $logRecord['context']['buildID'] = $build->getId(); + unset($logRecord['context']['build']); + } + } + return $logRecord; + } +} \ No newline at end of file From a453571fcbabe9a79aaca1370be3325c0ad5b0aa Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sun, 27 Oct 2013 14:25:43 +0000 Subject: [PATCH 7/8] Adding the LoggedBuildContextTidier to the monolog logging so that the build id is added to log messages. --- PHPCI/Command/RunCommand.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PHPCI/Command/RunCommand.php b/PHPCI/Command/RunCommand.php index 26ef6c1e..1efe68d1 100644 --- a/PHPCI/Command/RunCommand.php +++ b/PHPCI/Command/RunCommand.php @@ -11,6 +11,7 @@ namespace PHPCI\Command; use Monolog\Logger; use PHPCI\Helper\BuildDBLogHandler; +use PHPCI\Helper\LoggedBuildContextTidier; use PHPCI\Helper\OutputLogHandler; use Psr\Log\LoggerAwareInterface; use Symfony\Component\Console\Command\Command; @@ -63,6 +64,8 @@ class RunCommand extends Command ); } + $logger->pushProcessor(new LoggedBuildContextTidier()); + foreach ($result['items'] as $build) { $builds++; From 35b3db13d8d1b0d742cf1885d6bfb376800c8345 Mon Sep 17 00:00:00 2001 From: meadsteve Date: Sun, 27 Oct 2013 14:26:37 +0000 Subject: [PATCH 8/8] Fixing more tab -> space conversion issues. --- PHPCI/Command/RunCommand.php | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/PHPCI/Command/RunCommand.php b/PHPCI/Command/RunCommand.php index 1efe68d1..2acf83dc 100644 --- a/PHPCI/Command/RunCommand.php +++ b/PHPCI/Command/RunCommand.php @@ -31,10 +31,10 @@ use PHPCI\BuildFactory; */ class RunCommand extends Command { - /** - * @var OutputInterface - */ - protected $output; + /** + * @var OutputInterface + */ + protected $output; protected function configure() { @@ -44,25 +44,25 @@ class RunCommand extends Command } /** - * Pulls all pending builds from the database and runs them. - */ + * Pulls all pending builds from the database and runs them. + */ protected function execute(InputInterface $input, OutputInterface $output) { $this->output = $output; - $logger = new Logger("BuildLog"); + $logger = new Logger("BuildLog"); - $store = Factory::getStore('Build'); + $store = Factory::getStore('Build'); $result = $store->getByStatus(0); $builds = 0; - // For verbose mode we want to output all informational and above - // messages to the symphony output interface. - if ($input->getOption('verbose')) { - $logger->pushHandler( - new OutputLogHandler($this->output, Logger::INFO) - ); - } + // For verbose mode we want to output all informational and above + // messages to the symphony output interface. + if ($input->getOption('verbose')) { + $logger->pushHandler( + new OutputLogHandler($this->output, Logger::INFO) + ); + } $logger->pushProcessor(new LoggedBuildContextTidier()); @@ -71,17 +71,17 @@ class RunCommand extends Command $build = BuildFactory::getBuild($build); - // Logging relevant to this build should be stored - // against the build itself. - $buildDbLog = new BuildDBLogHandler($build, Logger::INFO); - $logger->pushHandler($buildDbLog); + // Logging relevant to this build should be stored + // against the build itself. + $buildDbLog = new BuildDBLogHandler($build, Logger::INFO); + $logger->pushHandler($buildDbLog); - $builder = new Builder($build, $logger); + $builder = new Builder($build, $logger); $builder->execute(); - // After execution we no longer want to record the information - // back to this specific build so the handler should be removed. - $logger->popHandler($buildDbLog); + // After execution we no longer want to record the information + // back to this specific build so the handler should be removed. + $logger->popHandler($buildDbLog); } return $builds;