[pLog-svn] r911 - in plog/trunk: . class/logger class/logger/appender class/logger/config class/logger/layout class/logger/logger class/object class/template config

oscar at devel.plogworld.net oscar at devel.plogworld.net
Tue Feb 1 21:43:58 GMT 2005


Author: oscar
Date: 2005-02-01 21:43:57 +0000 (Tue, 01 Feb 2005)
New Revision: 911

Added:
   plog/trunk/class/logger/appender/
   plog/trunk/class/logger/appender/appender.class.php
   plog/trunk/class/logger/appender/fileappender.class.php
   plog/trunk/class/logger/appender/nullappender.class.php
   plog/trunk/class/logger/appender/stdoutappender.class.php
   plog/trunk/class/logger/config/
   plog/trunk/class/logger/config/loggerconfigloader.class.php
   plog/trunk/class/logger/layout/
   plog/trunk/class/logger/layout/layout.class.php
   plog/trunk/class/logger/layout/patternlayout.class.php
   plog/trunk/class/logger/logger/
   plog/trunk/class/logger/logger/loggedmessage.class.php
   plog/trunk/class/logger/logger/logger.class.php
   plog/trunk/class/logger/loggermanager.class.php
   plog/trunk/config/logging.properties.php
Removed:
   plog/trunk/class/logger/log4php/
   plog/trunk/class/logger/ploglogger.class.php
   plog/trunk/config/log4php.properties
Modified:
   plog/trunk/class/object/object.class.php
   plog/trunk/class/template/template.class.php
   plog/trunk/debug.php
   plog/trunk/trackback.php
Log:
removed log4php and added our own replacement. Started off as a small modification to our cousin project qframework's logger but ended up being a mixture of their solution, my approach and some concepts from log4php... Specially things like the ability to configure the whole thing from a config file, etc. 
This new logging implementation does exactly the same that log4php did but with a smaller memory footprint... Let's see if this solves the issue with excessive memory issue. I am sure it had something to do with log4php's huge size!

Added: plog/trunk/class/logger/appender/appender.class.php
===================================================================
--- plog/trunk/class/logger/appender/appender.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/appender/appender.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,75 @@
+<?php
+
+    /**
+     * qAppender allows you to log messags to any location. Every appender has its own layout
+	 * that specifies the format of the messages, and every appender has a target location for messages.
+	 * This way, we can have an appender that writes log messages to a database, another one that writes
+	 * messages to a file, etc.
+	 *
+	 * @see LoggerManager
+	 * @see Logger
+     */
+    class Appender
+    {
+        /**
+         * The layout to be used for this appender.
+         */
+        var $layout;
+		
+		/**
+		 * used to keep the properties
+		 * @private
+		 */
+		var $_properties;
+
+        /**
+         * Create a new Appender instance.
+         *
+         * @param Layout A Layout instance.
+         */
+        function Appender(&$layout, $properties)
+        {
+            $this->layout =& $layout;
+			
+			$this->_properties = $properties;
+        }
+
+        /**
+         * Retrieve the layout this appender is using.
+         *
+         * @return Layout A Layout instance.
+         */
+        function & getLayout ()
+        {
+            return $this->layout;
+        }
+
+        /**
+         * Set the layout this appender will use.
+         *
+         * @param Layout A Layout instance.
+         */
+        function setLayout (&$layout)
+        {
+            $this->layout =& $layout;
+        }
+
+        /**
+         * Write to this appender.
+         *
+         * <br/><br/>
+         *
+         * <note>
+         *     This should never be called manually.
+         * </note>
+         *
+         * @param message The message to write.
+         */
+        function write ($message)
+        {
+            throw(new Exception("Appender::write: This method must be implemented by child classes."));
+            die();
+        }
+    }
+
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/appender/fileappender.class.php
===================================================================
--- plog/trunk/class/logger/appender/fileappender.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/appender/fileappender.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,85 @@
+<?php
+
+	/**
+	 * @package logger
+	 */
+
+	include_once( PLOG_CLASS_PATH."class/logger/appender/appender.class.php" );
+
+    /**
+     * FileAppender allows a logger to write a message to file.
+     */
+    class FileAppender extends Appender
+    {
+        /**
+         * An absolute file-system path to the log file.
+         */
+        var $file;
+
+        /**
+         * A pointer to the log file.
+         *
+         * @access private
+         * @since  1.0
+         * @type   resource
+         */
+        var $fp;
+
+        /**
+         * Create a new qFileAppender instance.
+		 *
+         *
+         * @param Layout A Layout instance.
+		 * @param properties An associative array with properties that might be needed by this
+		 * appender
+         * @access public
+         * @since  1.0
+		 * @see qAppender
+         */
+        function FileAppender ($layout, $properties)
+        {
+            parent::Appender($layout, $properties);
+
+            $this->file    =  $properties["file"];
+
+            $this->openFP();
+        }
+
+        /**
+         * Open the file pointer.
+         *
+         * <br/><br/>
+         *
+         * <note>
+         *     This should never be called manually.
+         * </note>
+         */
+        function openFP()
+        {		
+            $this->fp   = fopen( $this->file, "a+" );
+			if( !$this->fp ) {
+				throw( new Exception( "Cannot open log file: ".$this->file ));
+				die();
+			}
+			
+			return true;
+        }
+
+        /**
+         * Write a message to the log file.
+         *
+         * <br/><br/>
+         *
+         * <note>
+         *     This should never be called manually.
+         * </note>
+         *
+         * @param string The message to write.
+         */
+        function write ($message)
+        {
+			fwrite( $this->fp, $message );
+        }
+    }
+
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/appender/nullappender.class.php
===================================================================
--- plog/trunk/class/logger/appender/nullappender.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/appender/nullappender.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,21 @@
+<?php
+
+    include_once(PLOG_CLASS_PATH."class/logger/appender/appender.class.php");
+
+    /**
+	 * Dummy appender that does nothing.
+	 *
+	 * @package logger
+     */
+    class NullAppender extends Appender
+    {
+        /**
+		 * This method does nothing since this is a dummy appender anyway!
+         */
+        function write ($message)
+        {
+			return( true );
+        }
+    }
+
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/appender/stdoutappender.class.php
===================================================================
--- plog/trunk/class/logger/appender/stdoutappender.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/appender/stdoutappender.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,36 @@
+<?php
+
+    include_once(PLOG_CLASS_PATH."class/logger/appender/appender.class.php");
+
+    /**
+     * StdoutAppender logs a message directly to the requesting client.
+	 *
+	 * @package logger
+     */
+    class StdoutAppender extends Appender
+    {
+        /**
+         * Create a new FileAppender instance.
+         *
+         * @param Layout A Layout instance.
+         *
+         * @access public
+         * @since  1.0
+         */
+        function StdoutAppender($layout, $properties)
+        {
+            parent::Appender($layout, $properties);
+        }
+
+        /**
+         * Write a message directly to the client, including the new line.
+		 *
+		 * @param message The message that we're going to write
+         */
+        function write ($message)
+        {
+            echo $message . "<br/>\n";
+        }
+    }
+
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/config/loggerconfigloader.class.php
===================================================================
--- plog/trunk/class/logger/config/loggerconfigloader.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/config/loggerconfigloader.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,111 @@
+<?php
+
+	define( "LOGGER_DEFAULT_CONFIG_FILE_PATH", "config/logging.properties.php" );
+	
+	include_once( PLOG_CLASS_PATH."class/file/file.class.php" );
+
+	/**
+	 * loads the config file of the logger. By default it uses config/logging.properties.php
+	 * as the config file. See the documentation for the LoggerManager for more details on how
+	 * the configuration file should be laid out.
+	 */
+	class LoggerConfigLoader
+	{
+	
+		/**
+		 * array used to store the keys
+		 */
+		var $_keys;
+	
+		function LoggerConfigLoader( $defaultFilePath = LOGGER_DEFAULT_CONFIG_FILE_PATH )
+		{
+			// load the config file if it is readable
+			if( File::isReadable( $defaultFilePath )) {
+				include_once( $defaultFilePath );
+				$this->_keys = $config;
+			}
+			else {
+				throw( new Exception( "There was an error loading logger config file: $defaultFilePath" ));
+				die();
+			}
+		}
+		
+		/**
+		 * @param key
+		 * @return Returns the value assigned to the given key
+		 */
+		function getValue( $key )
+		{
+			return( $this->_keys[$key] );
+		}
+		
+		/**
+		 * returns a list of all the configured loggers
+		 *
+		 * @return An arrary with all the configured loggers
+		 */
+		function getConfiguredLoggers()
+		{		
+			return( array_keys( $this->_keys ));
+		}
+		
+		/**
+		 * returns all the properties given a logger
+		 *
+		 * @param logger The logger name
+		 * @return An associative array
+		 */
+		function getLoggerProperties( $logger )
+		{
+			return( $this->getValue( $logger ));
+		}
+		
+		/**
+		 * returns the default layout for a given logger
+		 *
+		 * @param logger The logger name
+		 * @return The layout/pattern for messages logged via this logger
+		 */
+		function getLoggerLayout( $logger )
+		{
+			return( $this->getLoggerProperty( $logger, "layout" ));
+		}
+		
+		/**
+		 * returns the filename where the given logger is going to write its messages
+		 *
+		 * @param logger The logger name
+		 * @return The filename. But this parameter is only meaningful for loggers writing to a file!
+		 */
+		function getLoggerFilename( $logger )
+		{
+			return( $this->getLoggerProperty( $logger, "file" ));
+		}
+		
+		/**
+		 * returns the appender used by the given logger
+		 *
+		 * @param logger the logger name
+		 * @return the appender configured for this logger
+		 */
+		function getLoggerAppender( $logger )
+		{
+			return( $this->getLoggerProperty( $logger, "appender" ));
+		}
+		
+		/**
+		 * returns all properties of a given logger
+		 *
+		 * @param logger The logger name
+		 * @param property The property name
+		 * @private
+		 * @return the value of the property for the given logger
+		 */
+		function getLoggerProperty( $logger, $property )
+		{
+			$loggerProperties = $this->getLoggerProperties( $logger );
+			
+			return( $loggerProperties[$property] );		
+		}
+	}
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/layout/layout.class.php
===================================================================
--- plog/trunk/class/logger/layout/layout.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/layout/layout.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,45 @@
+<?php
+
+	include_once( PLOG_CLASS_PATH."class/object/object.class.php" );
+	
+	/**
+	 * @package logger
+	 */
+
+    /**
+     * Layout provides a customizable way to format data for an appender. A Layout specifies
+	 * the format of the messages that are going to be written to a target via an appender.
+	 *
+	 * @see Appender
+	 * @see Logger
+	 * @see LoggerManager
+     */
+    class Layout
+    {
+        /**
+         * Create a new Layout instance.
+         */
+        function Layout()
+        {
+			// nuttin' :)
+        }
+
+        /**
+         * Format a message.
+         *
+         * <br/><br/>
+         *
+         * <note>
+         *     This should never be called manually.
+         * </note>
+         *
+         * @param Message A LoggedMessage instance.
+         */
+        function &format (&$message)
+        {
+            throw(new Exception("Layout::format(&$message) must be overridden"));
+            die();
+        }
+    }
+
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/layout/patternlayout.class.php
===================================================================
--- plog/trunk/class/logger/layout/patternlayout.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/layout/patternlayout.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,97 @@
+<?php
+
+    include_once(PLOG_CLASS_PATH."class/logger/layout/layout.class.php");
+
+    /**
+     * PatternLayout allows a completely customizable layout that uses a conversion
+     * pattern for formatting.
+     *
+	 * @package logger
+     */
+    class PatternLayout extends Layout
+    {
+        /**
+         * The message to be formatted.
+         */
+        var $message;
+
+        /**
+         * The conversion pattern to use with this layout.
+         */
+        var $pattern;
+
+        /**
+         * Create a new PatternLayout instance.
+         */
+        function PatternLayout ($pattern)
+        {
+			parent::Layout( $pattern );
+			
+			$this->pattern = $pattern;
+        }
+		
+		/**
+		 * @private
+		 * Returns a number given a priority string
+		 */
+		function getPriorityNumber( $prio )
+		{
+			$value = 0;
+		
+			switch( $prio ) {
+				case LOGGER_PRIO_INFO: $value = 1; break;
+				case LOGGER_PRIO_WARN: $value = 2; break;
+				case LOGGER_PRIO_ERROR: $value = 3; break;
+				case LOGGER_PRIO_DEBUG: $value = 4; break;												
+			}
+			
+			return( $value );
+		}
+
+        /**
+         * Format a log message.
+         *
+         *
+         * <b>Conversion characters:</b>
+         *
+         * <ul>
+         *     <li><b>%c</b>               - the class where message was logged</li>
+         *     <li><b>%d</b>               - current date</li>
+         *     <li><b>%f</b>               - the file where the message was logged</li>
+         *     <li><b>%F</b>               - the function where the message was
+         *                                   logged</li>
+         *     <li><b>%l</b>               - the line where the message was logged</li>
+         *     <li><b>%m</b>               - the log message</li>
+         *     <li><b>%n</b>               - a newline</li>
+         *     <li><b>%N</b>               - the level name</li>
+         *     <li><b>%p</b>               - the level of priority</li>
+         *     <li><b>%r</b>               - a carriage return</li>
+         *     <li><b>%t</b>               - a horizontal tab</li>
+         *     <li><b>%T</b>               - a unix timestamp (seconds since January
+         *                                   1st, 1970)</li>
+         * </ul>
+         *
+         * @param Message A Message instance.
+         *
+         * @return string A formatted log message.
+         */
+        function &format (&$message)
+        {		
+			$pattern = str_replace( "%c", $message->class, $this->pattern );
+			$pattern = str_replace( "%d", strftime("%d-%m-%Y %H:%M:%S", time()), $pattern );
+			$pattern = str_replace( "%f", $message->file, $pattern );
+			$pattern = str_replace( "%F", $message->function, $pattern );
+			$pattern = str_replace( "%l", $message->line, $pattern );
+			$pattern = str_replace( "%m", $message->getMessage(), $pattern );
+			$pattern = str_replace( "%n", "\n", $pattern );
+			$pattern = str_replace( "%N", strtoupper( $message->getParameter("prio")), $pattern );
+			$pattern = str_replace( "%p", strtoupper( $this->getPriorityNumber($message->getParameter("prio"))), $pattern );
+			$pattern = str_replace( "%r", "\r", $pattern );
+			$pattern = str_replace( "%t", "\t", $pattern );
+			$pattern = str_replace( "%T", time(), $pattern );
+			
+			return( $pattern );
+        }
+    }
+
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/logger/loggedmessage.class.php
===================================================================
--- plog/trunk/class/logger/logger/loggedmessage.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/logger/loggedmessage.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,135 @@
+<?php
+
+    include_once(PLOG_CLASS_PATH."class/object/object.class.php");
+
+    /**
+     * LoggedMessage contains information about a log message such as priority, text
+	 * etc...
+     *
+     * @package logger
+     */
+    class LoggedMessage
+    {
+        /**
+         * An associative array of message parameters.
+         */
+        var $params;
+		
+		/**
+		 * public attributes that hold useful information
+		 */
+		var $class;
+		var $line;
+		var $fullFileName;
+		var $file;
+		var $args;
+		var $function;
+
+        /**
+         * Create a new qMessage instance.
+         *
+         * @param params An associative array of parameters.
+         */
+        function LoggedMessage($message = "", $params = NULL)
+        {
+			$this->_message = $message;
+			
+			$this->getLocationInfo();
+
+            $this->params = ($params == NULL) ? array() : $params;
+        }
+
+		/**
+		 * returns the string message that is going to be logged
+		 *
+		 * @return a string
+		 */
+		function getMessage()
+		{
+			return( $this->_message );
+		}
+
+        /**
+         * Retrieve a parameter.
+         *
+         * @param name A parameter name.
+         *
+         * @return string A parameter value, if a parameter with the given name
+         *                exists, otherwise <b>NULL</b>.
+         */
+        function &getParameter ($name)
+        {
+            if (isset($this->params[$name]))
+            {
+                return $this->params[$name];
+            }
+
+            return NULL;
+        }
+
+        /**
+         * Set a parameter.
+         *
+         * @param string A parameter name.
+         * @param string A parameter value.
+         */
+        function setParameter ($name, $value)
+        {
+            $this->params[$name] = $value;
+        }
+		
+		/**
+		 * @private
+		 * Returns a string representation of an array
+		 */
+		function _getParametersString( $paramArray )
+		{
+			$result = "";
+			
+			if( is_array( $paramArray )) {
+				foreach( $paramArray as $key => $value ) {
+					$result .= "$key => $value, ";
+				}
+			}
+			
+			return( $result );
+		}
+		
+		/**
+		 * get some nice information about location, file where the event was generated
+		 * etc. This information will only be available if the function debug_backtrace()
+		 * is available if not, no location information will be provided
+		 *
+		 * @return Returns always true. 
+		 */
+		function getLocationInfo()
+		{
+			if( function_exists( "debug_backtrace" )) {
+				// get the backtrace
+				$trace = debug_backtrace();
+				
+				// at the very bottom, we have the caller
+				//$callerInfo = array_pop( $trace );
+				$callerInfo = $trace[3];
+				
+				// fill in the information that we need
+				$this->fullFileName = $callerInfo["file"];
+				$this->file = basename( $this->fullFileName );
+				$this->line = $callerInfo["line"];
+				$this->class = $callerInfo["class"];
+				$this->args = $this->_getParametersString( $callerInfo["args"] );
+				$this->function = $callerInfo["function"];
+			}
+			else {
+				$this->fullFileName = "";
+				$this->line = "";
+				$this->file = "";
+				$this->class = "";
+				$this->args = "";
+				$this->function = "";
+			}
+			
+			return true;
+		}
+    }
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/logger/logger.class.php
===================================================================
--- plog/trunk/class/logger/logger/logger.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/logger/logger.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,166 @@
+<?php
+
+    include_once( PLOG_CLASS_PATH."class/object/object.class.php" );
+	include_once( PLOG_CLASS_PATH."class/logger/logger/loggedmessage.class.php" );
+	
+	/**
+	 * different priorities that can be used for logging
+	 */
+	define( "LOGGER_PRIO_INFO", "info" );
+	define( "LOGGER_PRIO_WARN", "warn" );
+	define( "LOGGER_PRIO_ERROR", "error" );
+	define( "LOGGER_PRIO_DEBUG", "debug" );
+
+    /**
+     * Logger provides an interface for logging messages to multiple appenders. A logger is the base
+	 * class used to log. Each logger has an appender (currently only one appender per logger) and
+	 * each appender has its own layout. Also each logger can have its own custom parameter that depend
+	 * on the logger such as priority, etc. 
+	 *
+	 * Loggers are defined in the configuration file (config/logger.properties.php) and it is usually
+	 * a better idea to access them via LoggerManager::getLogger($loggerId) Of course we can always built our
+	 * own custom loggers if needed.
+	 *
+	 * @see LoggerManager
+     */
+    class Logger
+    {
+        /**
+         * An associative array of appenders.
+         */
+        var $appenders;
+
+        /**
+         * Create a new Logger instance.
+         *
+         * @access public
+         * @since  1.0
+         */
+        function Logger( $loggerProperties )
+        {
+			// get the priority at which we're logging
+			$this->prio = $loggerProperties["prio"];
+        }
+
+		/**
+		 * Given a priority and the current priority used by this logger, returns
+		 * true whether this message is loggable or not.
+		 *
+		 * @param prio The priority which we're checking whether it is loggable or not
+		 * @return true if it is loggable or false if not
+		 */
+		function isLoggable( $prio )
+		{
+			$loggable = false;
+		
+			switch( $this->prio ) {
+				case LOGGER_PRIO_DEBUG:
+					$loggable = true;
+					break;
+				case LOGGER_PRIO_ERROR:
+					$loggable = ( $prio == LOGGER_PRIO_ERROR );
+					break;
+				case LOGGER_PRIO_WARN:
+					$loggable = ( $prio == LOGGER_PRIO_WARN || $prio == LOGGER_PRIO_ERROR );
+					break;
+				case LOGGER_PRIO_INFO:
+					$loggable = ( $prio != LOGGER_PRIO_DEBUG );
+					break;
+			}
+			
+			return( $loggable );
+		}
+
+        /**
+         * Add an appender.
+         *
+         * <br/><br/>
+         *
+         * <note>
+         *     If an appender with the given name already exists, an error will be
+         *     reported.
+         * </note>
+         *
+         * @param string   An appender name.
+         * @param Appender An Appender instance.
+         *
+         * @access public
+         * @since  1.0
+         */
+        function addAppender( $appender )
+        {
+            $this->appenders[] = $appender;
+            return;
+        }
+		
+		/**
+		 * logs a message to all appenders, using the given layout with priority DEBUG
+		 *
+		 * @param message
+		 * @return always true
+		 */
+		function debug( $message )
+		{
+			return( $this->log( $message, LOGGER_PRIO_DEBUG ));		
+		}
+
+		/**
+		 * logs a message to all appenders, using the given layout with priority INFO
+		 *
+		 * @param message
+		 * @return always true
+		 */		
+		function info( $message )
+		{
+			return( $this->log( $message, LOGGER_PRIO_INFO ));
+		}
+		
+		/**
+		 * logs a message to all appenders, using the given layout with priority WARN
+		 *
+		 * @param message
+		 * @return always true
+		 */		
+		function warn( $messsage )
+		{
+			return( $this->log( $message, LOGGER_PRIO_WARN ));		
+		}
+
+		/**
+		 * logs a message to all appenders, using the given layout with priority ERROR
+		 *
+		 * @param message
+		 * @return always true
+		 */		
+		function error( $message )
+		{
+			return( $this->log( $message, LOGGER_PRIO_ERROR ));
+		}
+
+        /**
+         * Log a message.
+         *
+         * @param Message A string to log
+         *
+		 * @private
+         */
+        function log( &$message, $prio )
+        {
+			if( $this->isLoggable( $prio )) {
+				// if the event is loggable, build the message and log it
+				$msgObject = new LoggedMessage( $message );
+				$msgObject->setParameter( "prio", $prio );
+		
+				// loop through appenders and write to each one
+				foreach( $this->appenders as $appender ) {
+					$layout   =& $appender->getLayout();
+					$result   =& $layout->format( $msgObject );
+					$appender->write($result);
+				}
+			}
+			
+			return true;
+        }
+    }
+
+?>
\ No newline at end of file

Added: plog/trunk/class/logger/loggermanager.class.php
===================================================================
--- plog/trunk/class/logger/loggermanager.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/loggermanager.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,185 @@
+<?php
+
+	include_once( PLOG_CLASS_PATH."class/logger/logger/logger.class.php" );
+	include_once( PLOG_CLASS_PATH."class/logger/config/loggerconfigloader.class.php" );
+	include_once( PLOG_CLASS_PATH."class/logger/layout/patternlayout.class.php" );
+
+	/**
+	 * manages a bunch of loggers configured in the config/logging.properties.php file. By default if no loggers
+	 * are specified it will create one logger called "default".
+	 * In order to define new loggers, the configuration file has to look like this:
+	 *
+	 * $config["logger_name"] = Array( 
+	 *       "appender" => "name_of_the_appender_class",
+	 *       "layout"   => "a pattern definition for the log messages",
+	 *       "file"     => "file_for_fileappender",
+	 *       "prio"     => "debug" );
+	 *
+	 * Where "logger_name" is the identifer that we will use later on in the call to LoggerManager::getLogger()
+	 * later on to retrieve a handle to this particular logger.
+	 * 
+	 * The available appenders are: "file", "stdout", "null"
+	 *   The FileAppender class writes data to a log file, which must be specified via a property called "file"
+	 *   The StdoutAppender class writes data to the console
+	 *   The NullAppender does not write data anywhere, it's a "dumb" logger that does nothing.
+	 *
+	 * Layout formats: 
+	 *   PatternLayout: allows to specify a pattern for our messages. Patterns are specified as follows:
+	 * <ul>
+	 *     <li><b>%c</b>               - the class where message was logged</li>
+	 *     <li><b>%d</b>               - current date</li>
+	 *     <li><b>%f</b>               - the file where the message was logged</li>
+	 *     <li><b>%F</b>               - the function where the message was
+	 *                                   logged</li>
+	 *     <li><b>%l</b>               - the line where the message was logged</li>
+	 *     <li><b>%m</b>               - the log message</li>
+	 *     <li><b>%n</b>               - a newline</li>
+	 *     <li><b>%N</b>               - the level name</li>
+	 *     <li><b>%p</b>               - the level of priority</li>
+	 *     <li><b>%r</b>               - a carriage return</li>
+	 *     <li><b>%t</b>               - a horizontal tab</li>
+	 *     <li><b>%T</b>               - a unix timestamp (seconds since January 1st, 1970)</li>
+	 * </ul>
+	 *
+	 * The available priorities are: debug > error > warn > info
+	 *
+	 * NOTE: There can only be one appender and one layout class per logger.
+	 *
+	 * In order to retrieve a handle to one of our loggers later on in our code, we should use
+	 * LoggerManager::getLogger()
+	 *
+	 *    $log =& LoggerManager::getLogger( "logger_name" );
+	 *    $log->debug( $message );
+	 *    ...
+	 *    $log->info( $message );
+	 */
+    class LoggerManager
+    {
+        /**
+         * An associative array of loggers.
+         */
+        var $loggers;
+
+        /**
+         * Create a new LogManager instance.
+         * This should never be called manually.
+         */
+        function LoggerManager()
+        {
+            $this->loggers = array();
+			
+			$this->_loadLoggerConfig();
+        }
+		
+		/**
+		 * @private
+		 * Loads the configuration from the config file
+		 */
+		function _loadLoggerConfig()
+		{
+			// load the config file and see how many loggers are configued
+			$config = new LoggerConfigLoader();
+			$loggers = $config->getConfiguredLoggers();
+			
+			if( count($loggers) == 0 ) {
+				// add a default logger
+				$loggers["default"] = Array( "layout" => "%d %N - [%f:%l (%c:%F)] %m%n",
+											 "appender" => "stdout",
+											 "prio" => "debug" );
+			}
+			
+			// loop through the loggers and configure them
+			foreach( $config->getConfiguredLoggers() as $logger ) {		
+				// get the logger config properties
+				$properties = $config->getLoggerProperties( $logger );
+				
+				// create the logger
+				$layout = new PatternLayout( $config->getLoggerLayout( $logger ));
+				$appenderObject = $this->createAppenderInstance( $config->getLoggerAppender( $logger ), $layout, $properties );
+				
+				// create the logger, set the appender and it to the list
+				$loggerObject = new Logger( $properties );
+				$loggerObject->addAppender( $appenderObject );
+				$this->addLogger( $logger, $loggerObject );
+			}
+		}
+		
+		/**
+		 * dynamically loads a layout formatter
+		 *
+		 * @param appenderName
+		 * @return a qLayout class
+		 */
+		function createAppenderInstance( $appender, $layout, $properties )
+		{
+			$appenderClassName = $appender."appender";
+			$appenderClassFile = PLOG_CLASS_PATH."class/logger/appender/".$appenderClassName.".class.php";
+			
+			// load the class but first check if it exists...
+			if( !File::isReadable( $appenderClassFile )) {
+				throw( new Exception( "Cannot find an appender suitable for appender type '$appender'" ));
+				die();
+			}
+			
+			// if so, load the class and create an object
+			include_once( $appenderClassFile );			
+			$appender = new $appenderClassName( $layout, $properties );
+			
+			return( $appender );
+		}
+
+        /**
+         * Add a logger.
+         * If a logger with the given name already exists, an error will be
+         * reported.
+         *
+         * @param string A logger name.
+         * @param Logger A Logger instance.
+         */
+        function addLogger ($name, $logger)
+        {
+            if (isset($this->loggers[$name])) {
+                throw(new Exception("LogManager::addLogger: LogManager already contains logger " . $name));
+                die();
+            }
+
+            $this->loggers[$name] = $logger;
+			
+            return;
+        }
+
+        /**
+         * Retrieve the single instance of LogManager.
+         *
+         * @return qLogManager A qLogManager instance.
+         */
+        function &getInstance()
+        {
+            static $instance = NULL;
+
+            if ($instance === NULL) {
+                $instance = new LoggerManager();
+            }
+
+            return $instance;
+        }
+
+        /**
+         * Retrieve a logger.
+         * If a name is not specified, the default logger is returned.
+         *
+         * @param string A logger name.
+         * @return Logger A Logger instance, if the given Logger exists, otherwise NULL.
+         */
+        function &getLogger ($name = "default")
+        {
+			$instance =& LoggerManager::getInstance();
+		
+            if (isset($instance->loggers[$name])) {
+                return $instance->loggers[$name];
+            }
+		
+            return NULL;
+        }
+    }
+?>
\ No newline at end of file

Deleted: plog/trunk/class/logger/ploglogger.class.php
===================================================================
--- plog/trunk/class/logger/ploglogger.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/logger/ploglogger.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -1,82 +0,0 @@
-<?php
-
-    /**
-     * @package logger
-     */
-
-    include_once( PLOG_CLASS_PATH."class/object/object.class.php" );
-    include_once( PLOG_CLASS_PATH."class/file/file.class.php" );
-    include_once( PLOG_CLASS_PATH."class/data/timestamp.class.php" );
-    include_once( PLOG_CLASS_PATH."class/logger/log4php/LoggerManager.php" );
-
-    // since all the methods in the class are static, we need a few
-    // global variabled to keep track of all the configuration options!
-    $_pLogLoggerLogFilePath;
-    $_pLogLoggerLogFileName;
-    $_plogLoggerLogEnabled;
-        
-    /**
-     * Logger class that will help in our debugging purposes, since we cannot really
-     * output anyting to the browser (uh, there's no browser involved this time! :)
-     */
-    class PlogLogger extends Object 
-    {
-        function setLogFilePath( $filePath, $fileName = null ) 
-        {
-            global $_pLogLoggerLogFilePath, $_pLogLoggerLogFileName, $_plogLoggerLogEnabled;
-            $_pLogLoggerLogFilePath = $filePath;
-			$_pLogLoggerLogFileName = $fileName;
-        }
-        
-        /**
-         * Enables or disables logging at will
-         *
-         * @param enabled Whether to enable or disable logging. 'true' by default
-         */
-        function setEnabled( $enabled = true )
-        {
-            global $_plogLoggerLogEnabled;
-            
-            $_plogLoggerLogEnabled = $enabled;
-        }
-		
-		
-		function log( $string )
-		{
-			$log =& LoggerManager::getLogger( "File" );
-			$log->debug( $string );
-			
-			return true;
-		}
-	
-        function _log( $string )
-        {
-            global $_pLogLoggerLogFilePath, $_pLogLoggerLogFileName, $_plogLoggerLogEnabled;
-            static $file;
-            
-            // nothing to do if logging is disabled
-            if( !$_plogLoggerLogEnabled )
-                return false;
-            
-            if( !$file ) {
-				$fileName = $_pLogLoggerLogFileName;
-                if( $fileName == null ) {
-                    // define a filename
-                    $fileName = $_pLogLoggerLogFilePath."/".basename($_SERVER["PHP_SELF"]).".log";
-                }
-				else {
-                    $fileName = $_pLogLoggerLogFilePath."/".$fileName;
-				}
-				
-                $file = new File( $fileName );
-                $file->open( "a+" );
-            }
-			
-            $t = new Timestamp();
-            $date = $t->getIsoDate();
-            $logLine = $date." - ".$string."\n";
-			
-            $file->write( $logLine );
-        }
-    }
-?>

Modified: plog/trunk/class/object/object.class.php
===================================================================
--- plog/trunk/class/object/object.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/object/object.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -12,16 +12,10 @@
 	 
  */	 
 	 
-    /**
-     * path to the configuration file for log4php. This needs to be done *before* we
-     * even include the LoggerManage from log4php
-     */
-    define( "LOG4PHP_CONFIGURATION", PLOG_CLASS_PATH."config/log4php.properties" ); 
-
     if(PHP_VERSION < 5)
 	    include_once( PLOG_CLASS_PATH."class/object/exception.class.php" );
 
-    include_once( PLOG_CLASS_PATH."class/logger/log4php/LoggerManager.php" );
+    include_once( PLOG_CLASS_PATH."class/logger/loggermanager.class.php" );
     include_once( PLOG_CLASS_PATH."class/logger/LogUtil.php" );
     include_once( PLOG_CLASS_PATH."debug.php" );
 
@@ -43,15 +37,8 @@
          */
 		function Object()
 		{
-            /*
-        $conf = array('mode' => 0644, 'timeFormat' => '%X %x');
-        $this->log = &Log::singleton('file', 
-            'tmp/plog.log', 
-            $this->className(), 
-            $conf);
-            */
 			// initialize logging
-			$this->log =& LoggerManager::getLogger( $this->className());
+			$this->log =& LoggerManager::getLogger( "default" );
 		}
 
         function __getObjectId()

Modified: plog/trunk/class/template/template.class.php
===================================================================
--- plog/trunk/class/template/template.class.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/class/template/template.class.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -7,16 +7,9 @@
 
     include_once( PLOG_CLASS_PATH.'class/template/smarty/Smarty.class.php' );
     include_once( PLOG_CLASS_PATH.'class/config/config.class.php' );
+	include_once( PLOG_CLASS_PATH.'class/logger/loggermanager.class.php' );
 
     /**
-     * path to the configuration file for log4php. This needs to be done *before* we
-     * even include the LoggerManage from log4php
-     */
-    if ( !defined("LOG4PHP_CONFIGURATION") )
-        define( "LOG4PHP_CONFIGURATION", PLOG_CLASS_PATH."config/log4php.properties" ); 
-    include_once( PLOG_CLASS_PATH."class/logger/log4php/LoggerManager.php" );
-
-    /**
      * Wrapper around the Smarty class, inspired by the article
      * http://zend.com/zend/tut/tutorial-stump.php
      *
@@ -45,7 +38,7 @@
         function Template( $templateFile )
         {
             // initialize logging
-            $this->log =& LoggerManager::getLogger( get_class($this));
+            $this->log =& LoggerManager::getLogger( "default" );
 
             // create the Smarty object and set the security values
             $this->Smarty();

Deleted: plog/trunk/config/log4php.properties
===================================================================
--- plog/trunk/config/log4php.properties	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/config/log4php.properties	2005-02-01 21:43:57 UTC (rev 911)
@@ -1,10 +0,0 @@
-log4php.debug = false
-log4php.rootLogger=DEBUG, A1
-log4php.appender.A1=LoggerAppenderFile
-log4php.appender.A1.File=tmp/plog.log
-log4php.appender.A1.layout=LoggerLayoutTTCC
-log4php.appender.A1.layout.threadPrinting=false
-log4php.appender.A1.layout.contextPrinting=false
-log4php.appender.A1.layout.microSecondsPrinting=false
-log4php.appender.A1.layout.categoryPrefixing=false
-log4php.appender.A1.layout.dateFormat=%d-%m-%Y %H:%M:%S
\ No newline at end of file

Added: plog/trunk/config/logging.properties.php
===================================================================
--- plog/trunk/config/logging.properties.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/config/logging.properties.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -0,0 +1,24 @@
+<?php
+#
+# configuration for the default logger. If it is generating
+# too much logs for your tatest, set "appender" to "null". This will
+# be disabled once the final version is out anyway...
+#
+$config["default"] = Array( 
+    "layout" => "%d %N - [%f:%l (%c:%F)] %m%n", 
+    "appender" => "file",
+	"file" => "tmp/plog.log",
+    "prio" => "debug"
+  );
+  
+#
+# special logger for the trackback.php script, it sends the data to 
+# tmp/trackback.log
+$config["trackback"] = Array(
+    "layout" => "%d %N - [%f:%l (%c:%F)] %m%n", 
+    "appender" => "file",
+	"file" => "tmp/trackback.log",
+    "prio" => "debug"
+  );
+
+?>

Modified: plog/trunk/debug.php
===================================================================
--- plog/trunk/debug.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/debug.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -1,6 +1,6 @@
 <?php
 
-	include_once( PLOG_CLASS_PATH."class/logger/ploglogger.class.php" );
+	include_once( PLOG_CLASS_PATH."class/logger/loggermanager.class.php" );
 
 	/**
      * Very stupid function that will hopefully replace all my
@@ -16,7 +16,7 @@
 	
 	function _debug( $params )
 	{
-		$log =& LoggerManager::getLogger( "Debug" );
+		$log = LoggerManager::getLogger();
 		$log->debug( $params );
 	}
 

Modified: plog/trunk/trackback.php
===================================================================
--- plog/trunk/trackback.php	2005-02-01 20:05:41 UTC (rev 910)
+++ plog/trunk/trackback.php	2005-02-01 21:43:57 UTC (rev 911)
@@ -67,7 +67,7 @@
 	function trackbackLog( $message )
 	{
 		if( TRACKBACK_DEBUG_ENABLED ) {
-			$logger =& LoggerManager::getLogger( "trackback.php" );
+			$logger =& LoggerManager::getLogger( "trackback" );
 			$logger->debug( $message );
 		}
 		




More information about the pLog-svn mailing list