pax_global_header00006660000000000000000000000064125306372050014515gustar00rootroot0000000000000052 comment=69615c0e8b4033169b45d58f778fd3ba638d1d52 analog-1.0.7-stable/000077500000000000000000000000001253063720500142335ustar00rootroot00000000000000analog-1.0.7-stable/.gitignore000066400000000000000000000000301253063720500162140ustar00rootroot00000000000000vendor/* /composer.lock analog-1.0.7-stable/.travis.yml000066400000000000000000000002601253063720500163420ustar00rootroot00000000000000language: php php: - 5.3 - 5.4 - 5.5 - 5.6 - 7.0 - hhvm before_script: composer install --no-interaction --prefer-source script: phpunit --coverage-text --verbose analog-1.0.7-stable/LICENSE000066400000000000000000000020641253063720500152420ustar00rootroot00000000000000The MIT License Copyright (c) 2012 Johnny Broadway Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. analog-1.0.7-stable/README.md000066400000000000000000000121751253063720500155200ustar00rootroot00000000000000## Analog - PHP 5.3+ micro logging package [![Build Status](https://travis-ci.org/jbroadway/analog.png)](https://travis-ci.org/jbroadway/analog) * Copyright: (c) 2012 Johnny Broadway * License: http://www.opensource.org/licenses/mit-license.php Click here to lend your support to: Analog and make a donation at www.pledgie.com ! A [MicroPHP](http://microphp.org/) logging package based on the idea of using closures for configurability and extensibility. It functions as a static class, but you can completely control the writing of log messages through a closure function (aka [anonymous functions](http://ca3.php.net/manual/en/functions.anonymous.php)), or use the `Analog\Logger` wrapper that implements the [PSR-3 specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). By default, this class will write to a file named `sys_get_temp_dir() . '/analog.txt'` using the format `"machine - date - level - message\n"`, making it usable with no customization necessary. Analog also comes with over a dozen pre-written handlers in the Analog/Handlers folder, with examples for each in the examples folder. These include: * Amon - Send logs to the [Amon](http://amon.cx/) server monitoring tool * Buffer - Buffer messages to send all at once (works with File, Mail, Stderr, and Variable handlers) * ChromeLogger - Sends messages to [Chrome Logger](http://craig.is/writing/chrome-logger) browser plugin * File - Append messages to a file * FirePHP - Send messages to [FirePHP](http://www.firephp.org/) browser plugin * GELF - Send message to the [Graylog2](http://www.graylog2.org/) log management server * Ignore - Do nothing * LevelBuffer - Buffer messages and send only if sufficient error level reached * Mail - Send email notices * Mongo - Save to MongoDB collection * Multi - Send different log levels to different handlers * Post - Send messages over HTTP POST to another machine * Stderr - Send messages to STDERR * Syslog - Send messages to syslog * Threshold - Only writes log messages above a certain threshold * Variable - Buffer messages to a variable reference. So while it's a micro class, it's highly extensible and very capable out of the box too. ### Rationale I wrote this because I wanted something very small and simple like [KLogger](https://github.com/katzgrau/KLogger), and preferably not torn out of a wider framework if possible. After searching, I wasn't happy with the single-purpose libraries I found. With KLogger for example, I didn't want an object instance but rather a static class, and I wanted more flexibility in the back-end. I also found some that had the flexibility also had more complexity, for example [Monolog](https://github.com/Seldaek/monolog) is 25 source files (not incl. tests). With closures, this seemed to be a good balance of small without sacrificing flexibility. > What about Analog, the logfile analyzer? Well, since it hasn't been updated > since 2004, I think it's safe to call a single-file PHP logging class the > same thing without it being considered stepping on toes :) ### Usage Basic usage, with a custom handler function: ```php mydb->log->insert ($info); }); // Log an alert Analog::log ('The sky is falling!', Analog::ALERT); // Log some debug info Analog::log ('Debugging info', Analog::DEBUG); ?> ``` Usage with [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md), [Composer](http://getcomposer.org/), and the FirePHP handler: 1\. Create a `composer.json` file in the root of your project with the following contents. ```json { "require": { "analog/analog": "dev-master" } } ``` 2\. Run `php composer.phar install` from the terminal in the root of your project. 3\. Include Composer's autoloader and use the `Analog\Analog` class. ```php ``` Usage with [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md), [Composer](http://getcomposer.org/), and the Variable handler: 1\. Create a `composer.json` file in the root of your project with the following contents. ```json { "require": { "analog/analog": "dev-master" } } ``` 2\. Run `php composer.phar install` from the terminal in the root of your project. 3\. Include Composer's autoloader and use the `Analog\Logger` class. ```php handler (Analog\Handler\Variable::init ($log)); $logger->alert ('Things are really happening right now!'); var_dump ($log); ?> ``` For more examples, see the [examples](https://github.com/jbroadway/analog/tree/master/examples) folder. analog-1.0.7-stable/composer.json000066400000000000000000000012131253063720500167520ustar00rootroot00000000000000{ "name": "analog/analog", "type": "library", "description": "PHP 5.3+ micro logging class that can be extended via closures. Includes several pre-built handlers including file, mail, syslog, HTTP post, and MongoDB.", "keywords": ["log", "logging", "logger", "syslog", "error", "debug", "debugging", "alerts"], "homepage": "https://github.com/jbroadway/analog", "license": "MIT", "authors": [ { "name": "Johnny Broadway", "email": "johnny@johnnybroadway.com", "homepage": "http://www.johnnybroadway.com/" } ], "require": { "psr/log": "1.*", "php": ">=5.3.2" }, "autoload": { "psr-0": { "Analog": "lib/" } } } analog-1.0.7-stable/examples/000077500000000000000000000000001253063720500160515ustar00rootroot00000000000000analog-1.0.7-stable/examples/SplClassLoader.php000066400000000000000000000120431253063720500214350ustar00rootroot00000000000000. */ /** * SplClassLoader implementation that implements the technical interoperability * standards for PHP 5.3 namespaces and class names. * * http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1 * * // Example which loads classes for the Doctrine Common package in the * // Doctrine\Common namespace. * $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine'); * $classLoader->register(); * * @license http://www.opensource.org/licenses/mit-license.html MIT License * @author Jonathan H. Wage * @author Roman S. Borschel * @author Matthew Weier O'Phinney * @author Kris Wallsmith * @author Fabien Potencier */ class SplClassLoader { private $_fileExtension = '.php'; private $_namespace; private $_includePath; private $_namespaceSeparator = '\\'; /** * Creates a new SplClassLoader that loads classes of the * specified namespace. * * @param string $ns The namespace to use. */ public function __construct($ns = null, $includePath = null) { $this->_namespace = $ns; $this->_includePath = $includePath; } /** * Sets the namespace separator used by classes in the namespace of this class loader. * * @param string $sep The separator to use. */ public function setNamespaceSeparator($sep) { $this->_namespaceSeparator = $sep; } /** * Gets the namespace seperator used by classes in the namespace of this class loader. * * @return void */ public function getNamespaceSeparator() { return $this->_namespaceSeparator; } /** * Sets the base include path for all class files in the namespace of this class loader. * * @param string $includePath */ public function setIncludePath($includePath) { $this->_includePath = $includePath; } /** * Gets the base include path for all class files in the namespace of this class loader. * * @return string $includePath */ public function getIncludePath() { return $this->_includePath; } /** * Sets the file extension of class files in the namespace of this class loader. * * @param string $fileExtension */ public function setFileExtension($fileExtension) { $this->_fileExtension = $fileExtension; } /** * Gets the file extension of class files in the namespace of this class loader. * * @return string $fileExtension */ public function getFileExtension() { return $this->_fileExtension; } /** * Installs this class loader on the SPL autoload stack. */ public function register() { spl_autoload_register(array($this, 'loadClass')); } /** * Uninstalls this class loader from the SPL autoloader stack. */ public function unregister() { spl_autoload_unregister(array($this, 'loadClass')); } /** * Loads the given class or interface. * * @param string $className The name of the class to load. * @return void */ public function loadClass($className) { if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) { $fileName = ''; $namespace = ''; if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) { $namespace = substr($className, 0, $lastNsPos); $className = substr($className, $lastNsPos + 1); $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; } $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension; require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName; } } } analog-1.0.7-stable/examples/amon.php000066400000000000000000000004321253063720500175130ustar00rootroot00000000000000analog-1.0.7-stable/examples/buffer.php000066400000000000000000000005061253063720500200340ustar00rootroot00000000000000analog-1.0.7-stable/examples/chromelogger.php000066400000000000000000000005361253063720500212430ustar00rootroot00000000000000analog-1.0.7-stable/examples/default.php000066400000000000000000000002351253063720500202060ustar00rootroot00000000000000analog-1.0.7-stable/examples/file.php000066400000000000000000000003351253063720500175020ustar00rootroot00000000000000analog-1.0.7-stable/examples/firephp.php000066400000000000000000000005511253063720500202200ustar00rootroot00000000000000analog-1.0.7-stable/examples/gelf.php000066400000000000000000000005261253063720500175020ustar00rootroot00000000000000analog-1.0.7-stable/examples/ignore.php000066400000000000000000000001701253063720500200430ustar00rootroot00000000000000analog-1.0.7-stable/examples/levelbuffer.php000066400000000000000000000010371253063720500210640ustar00rootroot00000000000000analog-1.0.7-stable/examples/mail.php000066400000000000000000000002641253063720500175060ustar00rootroot00000000000000analog-1.0.7-stable/examples/mongo.php000066400000000000000000000005551253063720500177060ustar00rootroot00000000000000testing->log->find (); foreach ($cur as $doc) { print_r ($doc); } $m->testing->log->remove (); ?> analog-1.0.7-stable/examples/multi.php000066400000000000000000000012001253063720500177050ustar00rootroot00000000000000 Analog\Handler\Variable::init ($errors), Analog::WARNING => Analog\Handler\Variable::init ($warnings), Analog::DEBUG => Analog\Handler\Variable::init ($debug) ))); Analog::log ('First error'); Analog::log ('Emergency!', Analog::URGENT); Analog::log ('A warning...', Analog::WARNING); Analog::log ('Some info', Analog::INFO); Analog::log ('Debugging output', Analog::DEBUG); echo $errors; echo "-----\n"; echo $warnings; echo "-----\n"; echo $debug; ?>analog-1.0.7-stable/examples/post.php000066400000000000000000000002631253063720500175500ustar00rootroot00000000000000analog-1.0.7-stable/examples/psr-0.php000066400000000000000000000004161253063720500175240ustar00rootroot00000000000000register (); use \Analog\Analog; $log = ''; Analog::handler (\Analog\Handler\Variable::init ($log)); Analog::log ('Test one'); Analog::log ('Test two'); echo $log; ?>analog-1.0.7-stable/examples/server.php000066400000000000000000000003561253063720500200740ustar00rootroot00000000000000analog-1.0.7-stable/examples/stderr.php000066400000000000000000000002031253063720500200600ustar00rootroot00000000000000analog-1.0.7-stable/examples/syslog.php000066400000000000000000000002331253063720500201000ustar00rootroot00000000000000analog-1.0.7-stable/examples/threshold.php000066400000000000000000000007441253063720500205630ustar00rootroot00000000000000analog-1.0.7-stable/examples/variable.php000066400000000000000000000002431253063720500203460ustar00rootroot00000000000000analog-1.0.7-stable/lib/000077500000000000000000000000001253063720500150015ustar00rootroot00000000000000analog-1.0.7-stable/lib/Analog.php000066400000000000000000000011721253063720500167140ustar00rootroot00000000000000mydb->log->insert ($info); * }); * * // Log an alert * Analog::log ('The sky is falling!', Analog::ALERT); * * // Log some debug info * Analog::log ('Debugging info', Analog::DEBUG); * * ?> * * @package Analog * @author Johnny Broadway */ class Analog { /** * List of severity levels. */ const URGENT = 0; // It's an emergency const ALERT = 1; // Immediate action required const CRITICAL = 2; // Critical conditions const ERROR = 3; // An error occurred const WARNING = 4; // Something unexpected happening const NOTICE = 5; // Something worth noting const INFO = 6; // Information, not an error const DEBUG = 7; // Debugging messages /** * The default format for log messages (machine, date, level, message) * written to a file. To change the order of items in the string, * use `%1$s` references. */ public static $format = "%s - %s - %d - %s\n"; /** * The default date/time format for log messages written to a file. * Feeds into the `$format` property. */ public static $date_format = 'Y-m-d H:i:s'; /** * Timezone for date/time values. */ public static $timezone = 'GMT'; /** * Default log level. */ public static $default_level = 3; /** * The method of saving the log output. See Analog::handler() * for details on setting this. */ private static $handler = null; /** * The name of the current machine, defaults to $_SERVER['SERVER_ADDR'] * on first call to format_message(), or 'localhost' if $_SERVER['SERVER_ADDR'] * is not set (e.g., during CLI use). */ public static $machine = null; /** * Handler getter/setter. If no handler is provided, it will set it to * sys_get_temp_dir() . '/analog.txt' as a default. Usage: * * Analog::handler ('my_log.txt'); * * Using a closure: * * Analog::handler (function ($msg) { * return error_log ($msg); * }); */ public static function handler ($handler = false) { if ($handler) { self::$handler = $handler; } elseif (! self::$handler) { self::$handler = realpath (sys_get_temp_dir ()) . DIRECTORY_SEPARATOR . 'analog.txt'; } return self::$handler; } /** * Get the log info as an associative array. */ private static function get_struct ($message, $level) { if (self::$machine === null) { self::$machine = (isset ($_SERVER['SERVER_ADDR'])) ? $_SERVER['SERVER_ADDR'] : 'localhost'; } $dt = new \DateTime ('now', new \DateTimeZone (self::$timezone)); return array ( 'machine' => self::$machine, 'date' => $dt->format (self::$date_format), 'level' => $level, 'message' => $message ); } /** * Write a raw message to the log using a function or the default * file logging. */ private static function write ($struct) { $handler = self::handler (); if (! $handler instanceof \Closure) { $handler = \Analog\Handler\File::init ($handler); } return $handler ($struct); } /** * This is the main function you will call to log messages. * Defaults to severity level Analog::ERROR, which can be * changed via the `$default_level` property. * Usage: * * Analog::log ('Debug info', Analog::DEBUG); */ public static function log ($message, $level = null) { $level = ($level !== null) ? $level : self::$default_level; return self::write (self::get_struct ($message, $level)); } /** * Shortcut method for Analog::log($info, Analog::URGENT) * Usage: * * Analog::urgent ('Debug info'); */ public static function urgent ($message) { return self::write (self::get_struct ($message, self::URGENT)); } /** * Shortcut method for Analog::log($info, Analog::ALERT) * Usage: * * Analog::alert ('Debug info'); */ public static function alert ($message) { return self::write (self::get_struct ($message, self::ALERT)); } /** * Shortcut method for Analog::log($info, Analog::ERROR) * Usage: * * Analog::error ('Debug info'); */ public static function error ($message) { return self::write (self::get_struct ($message, self::ERROR)); } /** * Shortcut method for Analog::log($info, Analog::WARNING) * Usage: * * Analog::warning ('Debug info'); */ public static function warning ($message) { return self::write (self::get_struct ($message, self::WARNING)); } /** * Shortcut method for Analog::log($info, Analog::NOTICE) * Usage: * * Analog::notice ('Debug info'); */ public static function notice ($message) { return self::write (self::get_struct ($message, self::NOTICE)); } /** * Shortcut method for Analog::log($info, Analog::INFO) * Usage: * * Analog::info ('Debug info'); */ public static function info ($message) { return self::write (self::get_struct ($message, self::INFO)); } /** * Shortcut method for Analog::log($info, Analog::DEBUG) * Usage: * * Analog::debug ('Debug info'); */ public static function debug ($message) { return self::write (self::get_struct ($message, self::DEBUG)); } }analog-1.0.7-stable/lib/Analog/Handler/000077500000000000000000000000001253063720500175575ustar00rootroot00000000000000analog-1.0.7-stable/lib/Analog/Handler/Amon.php000066400000000000000000000016411253063720500211640ustar00rootroot00000000000000 $host, 'port' => $port, 'application_key' => $key )); $tags = array ( 0 => 'urgent', 1 => 'alert', 2 => 'critical', 3 => 'error', 4 => 'warning', 5 => 'notice', 6 => 'info', 7 => 'debug' ); return function ($info) use ($tags) { \Amon::log ($info, array ($tags[$info['level']])); }; } }analog-1.0.7-stable/lib/Analog/Handler/Buffer.php000066400000000000000000000027101253063720500215010ustar00rootroot00000000000000 'LOG', \Analog\Analog::INFO => 'INFO', \Analog\Analog::NOTICE => 'INFO', \Analog\Analog::WARNING => 'WARN', \Analog\Analog::ERROR => 'ERROR', \Analog\Analog::CRITICAL => 'ERROR', \Analog\Analog::ALERT => 'ERROR', \Analog\Analog::URGENT => 'ERROR' ); /** * Message index increases by 1 each time a message is sent. */ private static $message_index = 1; /** * Formats a log header to be sent. */ public static function format_header ($info) { if (is_array ($info['message'])) { $extra = array ( 'Type' => self::$log_levels[$info['level']], 'File' => $info['message'][1], 'Line' => $info['message'][2] ); $info['message'] = $info['message'][0]; } else { $extra = array ('Type' => self::$log_levels[$info['level']]); } $json = json_encode (array ($extra, $info['message'])); return sprintf ('X-Wf-1-1-1-%d: %s|%s|', self::$message_index++, strlen ($json), $json); } /** * Sends the initial headers if FirePHP is available then returns a * closure that handles sending log messages. */ public static function init () { if (! isset ($_SERVER['HTTP_USER_AGENT']) || preg_match ('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT']) || isset ($_SERVER['HTTP_X_FIREPHP_VERSION'])) { header ('X-Wf-Protocol-1: http://meta.wildfirehq.org/Protocol/JsonStream/0.2'); header ('X-Wf-1-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3'); header ('X-Wf-1-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'); } return function ($info) { header (FirePHP::format_header ($info)); }; } }analog-1.0.7-stable/lib/Analog/Handler/GELF.php000066400000000000000000000025561253063720500210150ustar00rootroot00000000000000setHost ($info['machine']); $message->setLevel ($info['level']); if (is_array ($info['message'])) { $message->setShortMessage ($info['message'][0]); $message->setFullMessage ($info['message'][0]); $message->setFile ($info['message'][1]); $message->setLine ($info['message'][2]); } else { $message->setShortMessage ($info['message']); $message->setFullMessage ($info['message']); } $publisher->publish ($message); }; } }analog-1.0.7-stable/lib/Analog/Handler/Ignore.php000066400000000000000000000004741253063720500215200ustar00rootroot00000000000000{$database}; } else { $conn = new \MongoClient ("mongodb://$server"); $db = $conn->{$database}; } return function ($info) use ($db, $collection) { $db->{$collection}->insert ($info); }; } } analog-1.0.7-stable/lib/Analog/Handler/Multi.php000066400000000000000000000025071253063720500213660ustar00rootroot00000000000000 array( * Analog\Handler\Mail::init( $to, $subject, $from ), * Analog\Handler\Stderr::init() * ), * * // Warnings are sent here * Analog::WARNING => Analog\Handler\File::init( 'logs/warnings.log' ), * * // Debug and info messages sent here * Analog::DEBUG => Analog\Handler\Ignore::init() // do nothing * ) ) ); * * // will be ignored * Analog::log ('Ignore me', Analog::DEBUG); * * // will be written to logs/warnings.log * Analog::log ('Log me', Analog::WARNING); * * // will trigger an email notice * Analog::log ('Uh oh...', Analog::ERROR); */ class Multi { public static function init ($handlers) { return function ($info) use ($handlers) { $level = is_numeric ($info['level']) ? $info['level'] : 3; while ($level <= 7) { if ( isset ( $handlers[ $level ] ) ) { if ( ! is_array( $handlers[ $level ] ) ) { $handlers[ $level ] = array( $handlers[ $level ] ); } foreach ( $handlers[ $level ] as $handler ) { $handler( $info ); } return; } $level++; } }; } }analog-1.0.7-stable/lib/Analog/Handler/Null.php000066400000000000000000000006451253063720500212070ustar00rootroot00000000000000 LOG_DEBUG, \Analog\Analog::INFO => LOG_INFO, \Analog\Analog::NOTICE => LOG_NOTICE, \Analog\Analog::WARNING => LOG_WARNING, \Analog\Analog::ERROR => LOG_ERR, \Analog\Analog::CRITICAL => LOG_CRIT, \Analog\Analog::ALERT => LOG_ALERT, \Analog\Analog::URGENT => LOG_EMERG ); public static $facilities = array ( 'auth' => LOG_AUTH, 'authpriv' => LOG_AUTHPRIV, 'cron' => LOG_CRON, 'daemon' => LOG_DAEMON, 'kern' => LOG_KERN, 'lpr' => LOG_LPR, 'mail' => LOG_MAIL, 'news' => LOG_NEWS, 'syslog' => LOG_SYSLOG, 'user' => LOG_USER, 'uucp' => LOG_UUCP ); public static function init ($ident, $facility) { if (! defined ('PHP_WINDOWS_VERSION_BUILD')) { self::$facilities['local0'] = LOG_LOCAL0; self::$facilities['local1'] = LOG_LOCAL1; self::$facilities['local2'] = LOG_LOCAL2; self::$facilities['local3'] = LOG_LOCAL3; self::$facilities['local4'] = LOG_LOCAL4; self::$facilities['local5'] = LOG_LOCAL5; self::$facilities['local6'] = LOG_LOCAL6; self::$facilities['local7'] = LOG_LOCAL7; } if (array_key_exists (strtolower ($facility), self::$facilities)) { $facility = self::$facilities[strtolower ($facility)]; } elseif (! in_array ($facility, array_values (self::$facilities), true)) { throw new \UnexpectedValueException ('Unknown facility value "' . $facility . '"'); } return function ($info) use ($ident, $facility) { if (! openlog ($ident, LOG_PID, $facility)) { throw new \LogicException ('Can\'t open syslog for ident "' . $ident . '" and facility "' . $facility . '"'); } syslog (Syslog::$levels[$info['level']], vsprintf ('%1$s: %4$s', $info)); closelog (); }; } } analog-1.0.7-stable/lib/Analog/Handler/Threshold.php000066400000000000000000000017741253063720500222350ustar00rootroot00000000000000notice ('Things are really happening right now.'); * * ?> * * @package Analog * @author Johnny Broadway */ class Logger implements LoggerInterface { /** * Converts from PSR-3 log levels to Analog log levels. */ public function convert_log_level ($level, $reverse = false) { if ($reverse) { switch ($level) { case Analog::URGENT: return LogLevel::EMERGENCY; case Analog::ALERT: return LogLevel::ALERT; case Analog::CRITICAL: return LogLevel::CRITICAL; case Analog::ERROR: return LogLevel::ERROR; case Analog::WARNING: return LogLevel::WARNING; case Analog::NOTICE: return LogLevel::NOTICE; case Analog::INFO: return LogLevel::INFO; case Analog::DEBUG: return LogLevel::DEBUG; } throw new InvalidArgumentException ('Level "' . $level . '" is not defined.'); } else { switch ($level) { case LogLevel::EMERGENCY: return Analog::URGENT; case LogLevel::ALERT: return Analog::ALERT; case LogLevel::CRITICAL: return Analog::CRITICAL; case LogLevel::ERROR: return Analog::ERROR; case LogLevel::WARNING: return Analog::WARNING; case LogLevel::NOTICE: return Analog::NOTICE; case LogLevel::INFO: return Analog::INFO; case LogLevel::DEBUG: return Analog::DEBUG; } throw new InvalidArgumentException ('Level "' . $level . '" is not defined.'); } } /** * Interpolates context values into the message placeholders. */ private function interpolate ($message, array $context = array ()) { if (is_array ($message)) { return $message; } // build a replacement array with braces around the context keys $replace = array (); foreach ($context as $key => $val) { if (is_object ($val) && get_class ($val) === 'DateTime') { $val = $val->format ('Y-m-d H:i:s'); } elseif (is_object ($val)) { $val = json_encode ($val); } elseif (is_array ($val)) { $val = json_encode ($val); } elseif (is_resource ($val)) { $val = (string) $val; } $replace['{' . $key . '}'] = $val; } // interpolate replacement values into the the message and return return strtr ($message, $replace); } /** * Sets the Analog log handler. */ public function handler ($handler) { Analog::handler ($handler); } /** * Sets the log message format. */ public function format ($format) { Analog::$format = $format; } /** * System is unusable. */ public function emergency ($message, array $context = array ()) { $this->_log (Analog::URGENT, $message, $context); } /** * Action must be taken immediately. */ public function alert ($message, array $context = array ()) { $this->_log (Analog::ALERT, $message, $context); } /** * Critical conditions. */ public function critical ($message, array $context = array ()) { $this->_log (Analog::CRITICAL, $message, $context); } /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. */ public function error ($message, array $context = array ()) { $this->_log (Analog::ERROR, $message, $context); } /** * Exceptional occurrences that are not errors. */ public function warning ($message, array $context = array ()) { $this->_log (Analog::WARNING, $message, $context); } /** * Normal but significant events. */ public function notice ($message, array $context = array ()) { $this->_log (Analog::NOTICE, $message, $context); } /** * Interesting events. */ public function info ($message, array $context = array ()) { $this->_log (Analog::INFO, $message, $context); } /** * Detailed debug information. */ public function debug ($message, array $context = array ()) { $this->_log (Analog::DEBUG, $message, $context); } /** * Logs with an arbitrary level. */ public function log ($level, $message, array $context = array ()) { $this->_log ( $this->convert_log_level ($level), $message, $context ); } /** * Perform the logging to Analog after the log level has been converted. */ private function _log ($level, $message, $context) { Analog::log ( $this->interpolate ($message, $context), $level ); } }analog-1.0.7-stable/lib/ChromePhp.php000066400000000000000000000235431253063720500174060ustar00rootroot00000000000000 */ class ChromePhp { /** * @var string */ const VERSION = '4.0.0'; /** * @var string */ const HEADER_NAME = 'X-ChromeLogger-Data'; /** * @var string */ const BACKTRACE_LEVEL = 'backtrace_level'; /** * @var string */ const LOG = 'log'; /** * @var string */ const WARN = 'warn'; /** * @var string */ const ERROR = 'error'; /** * @var string */ const GROUP = 'group'; /** * @var string */ const INFO = 'info'; /** * @var string */ const GROUP_END = 'groupEnd'; /** * @var string */ const GROUP_COLLAPSED = 'groupCollapsed'; /** * @var string */ protected $_php_version; /** * @var int */ protected $_timestamp; /** * @var array */ protected $_json = array( 'version' => self::VERSION, 'columns' => array('log', 'backtrace', 'type'), 'rows' => array() ); /** * @var array */ protected $_backtraces = array(); /** * @var bool */ protected $_error_triggered = false; /** * @var array */ protected $_settings = array( self::BACKTRACE_LEVEL => 1 ); /** * @var ChromePhp */ protected static $_instance; /** * Prevent recursion when working with objects referring to each other * * @var array */ protected $_processed = array(); /** * constructor */ private function __construct() { $this->_php_version = phpversion(); $this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time(); $this->_json['request_uri'] = $_SERVER['REQUEST_URI']; } /** * gets instance of this class * * @return ChromePhp */ public static function getInstance() { if (self::$_instance === null) { self::$_instance = new self(); } return self::$_instance; } /** * logs a variable to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function log() { return self::_log('', func_get_args()); } /** * logs a warning to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function warn() { return self::_log(self::WARN, func_get_args()); } /** * logs an error to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function error() { return self::_log(self::ERROR, func_get_args()); } /** * sends a group log * * @param string value */ public static function group() { return self::_log(self::GROUP, func_get_args()); } /** * sends an info log * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function info() { return self::_log(self::INFO, func_get_args()); } /** * sends a collapsed group log * * @param string value */ public static function groupCollapsed() { return self::_log(self::GROUP_COLLAPSED, func_get_args()); } /** * ends a group log * * @param string value */ public static function groupEnd() { return self::_log(self::GROUP_END, func_get_args()); } /** * internal logging call * * @param string $type * @return void */ protected static function _log($type, array $args) { // nothing passed in, don't do anything if (count($args) == 0 && $type != self::GROUP_END) { return; } $logger = self::getInstance(); $logger->_processed = array(); $logs = array(); foreach ($args as $arg) { $logs[] = $logger->_convert($arg); } $backtrace = debug_backtrace(false); $level = $logger->getSetting(self::BACKTRACE_LEVEL); $backtrace_message = 'unknown'; if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) { $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line']; } $logger->_addRow($logs, $backtrace_message, $type); } /** * converts an object to a better format for logging * * @param Object * @return array */ protected function _convert($object) { // if this isn't an object then just return it if (!is_object($object)) { return $object; } //Mark this object as processed so we don't convert it twice and it //Also avoid recursion when objects refer to each other $this->_processed[] = $object; $object_as_array = array(); // first add the class name $object_as_array['___class_name'] = get_class($object); // loop through object vars $object_vars = get_object_vars($object); foreach ($object_vars as $key => $value) { // same instance as parent object if ($value === $object || in_array($value, $this->_processed, true)) { $value = 'recursion - parent object [' . get_class($value) . ']'; } $object_as_array[$key] = $this->_convert($value); } $reflection = new ReflectionClass($object); // loop through the properties and add those foreach ($reflection->getProperties() as $property) { // if one of these properties was already added above then ignore it if (array_key_exists($property->getName(), $object_vars)) { continue; } $type = $this->_getPropertyKey($property); if ($this->_php_version >= 5.3) { $property->setAccessible(true); } try { $value = $property->getValue($object); } catch (ReflectionException $e) { $value = 'only PHP 5.3 can access private/protected properties'; } // same instance as parent object if ($value === $object || in_array($value, $this->_processed, true)) { $value = 'recursion - parent object [' . get_class($value) . ']'; } $object_as_array[$type] = $this->_convert($value); } return $object_as_array; } /** * takes a reflection property and returns a nicely formatted key of the property name * * @param ReflectionProperty * @return string */ protected function _getPropertyKey(ReflectionProperty $property) { $static = $property->isStatic() ? ' static' : ''; if ($property->isPublic()) { return 'public' . $static . ' ' . $property->getName(); } if ($property->isProtected()) { return 'protected' . $static . ' ' . $property->getName(); } if ($property->isPrivate()) { return 'private' . $static . ' ' . $property->getName(); } } /** * adds a value to the data array * * @var mixed * @return void */ protected function _addRow(array $logs, $backtrace, $type) { // if this is logged on the same line for example in a loop, set it to null to save space if (in_array($backtrace, $this->_backtraces)) { $backtrace = null; } // for group, groupEnd, and groupCollapsed // take out the backtrace since it is not useful if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) { $backtrace = null; } if ($backtrace !== null) { $this->_backtraces[] = $backtrace; } $row = array($logs, $backtrace, $type); $this->_json['rows'][] = $row; $this->_writeHeader($this->_json); } protected function _writeHeader($data) { header(self::HEADER_NAME . ': ' . $this->_encode($data)); } /** * encodes the data to be sent along with the request * * @param array $data * @return string */ protected function _encode($data) { return base64_encode(utf8_encode(json_encode($data))); } /** * adds a setting * * @param string key * @param mixed value * @return void */ public function addSetting($key, $value) { $this->_settings[$key] = $value; } /** * add ability to set multiple settings in one call * * @param array $settings * @return void */ public function addSettings(array $settings) { foreach ($settings as $key => $value) { $this->addSetting($key, $value); } } /** * gets a setting * * @param string key * @return mixed */ public function getSetting($key) { if (!isset($this->_settings[$key])) { return null; } return $this->_settings[$key]; } }analog-1.0.7-stable/phpunit.xml.dist000066400000000000000000000011521253063720500174050ustar00rootroot00000000000000 ./tests analog-1.0.7-stable/tests/000077500000000000000000000000001253063720500153755ustar00rootroot00000000000000analog-1.0.7-stable/tests/AnalogTest.php000066400000000000000000000071561253063720500201600ustar00rootroot00000000000000assertStringMatchesFormat ( "localhost - %d-%d-%d %d:%d:%d - 3 - Foo\n", file_get_contents (Analog::handler ()) ); unlink (Analog::handler ()); } /** * @depends test_default */ function test_format () { // Test changing the format string and write again Analog::$format = "%s, %s, %d, %s\n"; Analog::log ('Foo'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 3, Foo\n", file_get_contents (Analog::handler ()) ); unlink (Analog::handler ()); } /** * @depends test_format */ function test_tz_and_dates () { // Test changing the date_format Analog::$date_format = 'r'; // RFC2822 format Analog::log ('Foo'); $this->assertStringMatchesFormat ( "localhost, %s, %d %s %d %d:%d:%d +0000, 3, Foo\n", file_get_contents (Analog::handler ()) ); unlink (Analog::handler ()); // Test changing the timezone Analog::$timezone = 'CST'; Analog::log ('Foo'); $dt = new \DateTime ('now', new \DateTimeZone (Analog::$timezone)); $zone_offset = $dt->format ('O'); $this->assertStringMatchesFormat ( "localhost, %s, %d %s %d %d:%d:%d $zone_offset, 3, Foo\n", file_get_contents (Analog::handler ()) ); unlink (Analog::handler ()); Analog::$date_format = 'Y-m-d H:i:s'; Analog::$timezone = 'GMT'; } /** * @depends test_tz_and_dates */ function test_handler () { // Test logging using a closure Analog::handler (function ($msg) { AnalogTest::$log .= vsprintf (Analog::$format, $msg); }); Analog::log ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 3, Testing\n", self::$log ); self::$log = ''; } /** * @depends test_handler */ function test_level () { // Test default_level change Analog::$default_level = 1; Analog::log ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 1, Testing\n", self::$log ); Analog::$default_level = 3; } /* * @depends test_level * @covers Analog::urgent * @covers Analog::alert * @covers Analog::critical * @covers Analog::error * @covers Analog::warning * @covers Analog::notice * @covers Analog::info * @covers Analog::debug */ function test_aliases () { self::$log = ''; Analog::urgent ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 0, Testing\n", self::$log ); self::$log = ''; Analog::alert ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 1, Testing\n", self::$log ); self::$log = ''; Analog::error ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 3, Testing\n", self::$log ); self::$log = ''; Analog::warning ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 4, Testing\n", self::$log ); self::$log = ''; Analog::notice ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 5, Testing\n", self::$log ); self::$log = ''; Analog::info ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 6, Testing\n", self::$log ); self::$log = ''; Analog::debug ('Testing'); $this->assertStringMatchesFormat ( "localhost, %d-%d-%d %d:%d:%d, 7, Testing\n", self::$log ); self::$log = ''; } } ?>analog-1.0.7-stable/tests/PsrLogCompatTest.php000066400000000000000000000013031253063720500213150ustar00rootroot00000000000000handler (Variable::init ($this->log)); $logger->format ("%3\$d %4\$s\n"); return $logger; } public function getLogs () { $logger = $this->getLogger (); $logs = explode ("\n", trim ($this->log)); foreach ($logs as $key => $line) { list ($level, $msg) = explode (' ', $line, 2); $logs[$key] = $logger->convert_log_level ((int) $level, true) . ' ' . $msg; } return $logs; } }analog-1.0.7-stable/tests/bootstrap.php000066400000000000000000000003701253063720500201230ustar00rootroot00000000000000