diff --git a/src/Monolog/Formatter/WildfireFormatter.php b/src/Monolog/Formatter/WildfireFormatter.php new file mode 100644 index 00000000..dc4e656c --- /dev/null +++ b/src/Monolog/Formatter/WildfireFormatter.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Formatter; + +use Monolog\Logger; + +/** + * Serializes a log message according to Wildfire's header requirements + * + * @author Eric Clemmons (@ericclemmons) + */ +class WildfireFormatter extends LineFormatter implements FormatterInterface +{ + + /** + * Similar to LineFormatter::SIMPLE_FORMAT, except without the "[%datetime%]" + */ + const SIMPLE_FORMAT = "%channel%: %message% %extra%"; + + // Convert Logger's error levels to Wildfire's + const DEBUG = 'LOG'; + const INFO = 'INFO'; + const WARNING = 'WARN'; + const ERROR = 'ERROR'; + + /** + * {@inheritdoc} + */ + public function __construct($format = null, $dateFormat = null) + { + $this->format = $format ?: self::SIMPLE_FORMAT; + $this->dateFormat = $dateFormat ?: self::SIMPLE_DATE; + } + + /** + * {@inheritdoc} + */ + public function format(Array $record) + { + // Format record according with LineFormatter + $formatted = parent::format($record); + + // Create JSON object describing the appearance of the message in the console + $json = json_encode(array( + array( + 'Type' => constant('self::' . $record['level_name']), + 'File' => '', + 'Line' => '', + ), + $formatted['message'], + )); + + // The message itself is a serialization of the above JSON object + it's length + $formatted['message'] = sprintf( + '%s|%s|', + strlen($json), + $json + ); + + return $formatted; + } + +} \ No newline at end of file diff --git a/src/Monolog/Handler/FirePHPHandler.php b/src/Monolog/Handler/FirePHPHandler.php new file mode 100644 index 00000000..774bd084 --- /dev/null +++ b/src/Monolog/Handler/FirePHPHandler.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Monolog\Handler; + +use Monolog\Logger; +use Monolog\Formatter\WildfireFormatter; + +/** + * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. + * + * @author Eric Clemmons (@ericclemmons) + */ +class FirePHPHandler extends AbstractHandler +{ + + const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'; + + const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'; + + const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/ZendFramework/FirePHP/1.6.2'; + + private $prefix = 'X-Wf'; + + private $records = array(); + + protected function createHeader(Array $meta, $message) + { + return sprintf( + '%s-%s: %s', + $this->prefix, + join('-', $meta), + $message + ); + } + + protected function write(Array $record) + { + $this->records[] = $record; + } + + public function close() + { + if (headers_sent()) { + return false; + } else { + foreach ($this->getHeaders() as $header) { + header($header); + } + + return true; + } + } + + public function getHeaders() + { + // Wildfire is extensible to support multiple protocols & plugins in a single request, + // but we're not taking advantage of that (yet) for simplicity's sake. + // (It does help understanding header formatting, though!) + $protocolIndex = 1; + $structureIndex = 1; + $pluginIndex = 1; + $messageIndex = 1; + + // Initial payload consists of required headers for Wildfire + $headers = array( + $this->createHeader(array('Protocol', $protocolIndex), self::PROTOCOL_URI), + $this->createHeader(array($protocolIndex, 'Structure', $structureIndex), self::STRUCTURE_URI), + $this->createHeader(array($protocolIndex, 'Plugin', $pluginIndex), self::PLUGIN_URI), + ); + + foreach ($this->records as $record) { + $headers[] = $this->createHeader( + array($protocolIndex, $structureIndex, $pluginIndex, $messageIndex++), + $record['message'] + ); + } + + return $headers; + } + + protected function getDefaultFormatter() + { + return new WildfireFormatter(); + } + +} \ No newline at end of file