<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements. See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at
 
         http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">

	<properties>
		<title>Renderers</title>
	</properties>

	<body>
		<section name="Renderers">
			<p>Apache log4php can log more than just string messages. If you try to log an object it will be converted
			to a string and logged. The component which converts Objects to strings in log4php is called a 
			<em>renderer</em>.</p>
			
			<subsection name="Default renderer">
			
				<p>For example, let's say that an application uses a Person object, like this one:</p>
				
<pre class="prettyprint linenums"><![CDATA[
class Person {
    public $firstName;
    public $lastName;
    public $age;
}
]]></pre>

				<p>If you try logging it:</p>
								
<pre class="prettyprint linenums"><![CDATA[
$person = new Person();
$person->firstName = 'John';
$person->lastName = 'Doe';
$person->age = 37;

$logger = Logger::getLogger('main');
$logger->info("Here comes the person:");
$logger->info($person);
]]></pre>
				<p>Log4php will render it using the default renderer and you will end the output will look something 
				like:</p>
				
<pre class="prettyprint linenums"><![CDATA[
INFO - Here comes the person:
INFO - Person Object
(
    [firstName] => John
    [lastName] => Doe
    [age] => 37
)
]]></pre>
				
			</subsection>
			
			<subsection name="Creating a custom renderer">
				<p>In order to make log4php log the Person object in a more readable format, a custom renderer 
				class can be defined which will convert Person objects to a string suitable for logging.</p>
				
				<p>Let's call this renderer class PersonRenderer.</p>
				
<pre class="prettyprint linenums"><![CDATA[
/** All renderers must implement the LoggerRenderer interface. */
class PersonRenderer implements LoggerRenderer {
    public function render($person) {
        return "{$person->firstName} {$person->lastName} ({$person->age})";
    }
}
]]></pre>

				<p>Now log4php has to be configured to use PersonRenderer for rendering Person objects. This is done 
				in the configuration file.</p>

				<div class="auto-tabs">
					<ul>
						<li>XML</li>
						<li>PHP</li>
					</ul>
					
					<div class="tab-content">
						<div class="tab-pane">
<pre class="prettyprint linenums"><![CDATA[
<configuration xmlns="http://logging.apache.org/log4php/">
    <renderer renderedClass="Person" renderingClass="PersonRenderer" />
    <appender name="defualt" class="LoggerAppenderEcho" />
    <root>
        <appender_ref ref="defualt" />
    </root>
</configuration>
]]></pre>
						</div>
						<div class="tab-pane">
<pre class="prettyprint linenums"><![CDATA[
array(
    'renderers' => array(
        array(
            'renderedClass' => 'Person',
            'renderingClass' => 'PersonRenderer'
        )
    ),
    'appenders' => array(
        'default' => array(
            'class' => 'LoggerAppenderEcho',
        ),
    ),
    'rootLogger' => array(
        'appenders' => array('default'),
    ),
)
]]></pre>
						</div>
					</div>
				</div>
				
			
				<p>If the same code is run as above, the following output is produced:</p>
			
<pre class="prettyprint linenums"><![CDATA[
INFO - Here comes the person:
INFO - John Doe (37)
]]></pre>
				<p>Which is much more readable than the default rendering.</p>
			</subsection>
			
			<subsection name="Overriding the default renderer">
				<p>It is possible to set your own custom renderer as the default renderer.</p>
				
				<p>For example, if you're not happy with the way in which the default renderer converts objects, 
				you can create your own renderer:</p>
				   
<pre class="prettyprint linenums"><![CDATA[
class MyRenderer implements LoggerRenderer {
    public function render($input) {
        return var_dump($input);
    }
}
]]></pre>

				<p>And set it as the default renderer in the configuration:</p>
				
				<div class="auto-tabs">
					<ul>
						<li>XML</li>
						<li>PHP</li>
					</ul>
					
					<div class="tab-content">
						<div class="tab-pane">
<pre class="prettyprint linenums"><![CDATA[
<configuration xmlns="http://logging.apache.org/log4php/">
    <defaultRenderer renderingClass="MyRenderer" />
    <appender name="defualt" class="LoggerAppenderEcho" />
    <root>
        <appender_ref ref="defualt" />
    </root>
</configuration>
]]></pre>
						</div>
						<div class="tab-pane">
<pre class="prettyprint linenums"><![CDATA[
array(
    'defaultRenderer' => 'MyRenderer',
    'appenders' => array(
        'default' => array(
            'class' => 'LoggerAppenderEcho',
        ),
    ),
    'rootLogger' => array(
        'appenders' => array('default'),
    ),
)
]]></pre>
						</div>
					</div>
				</div>
				
				<p>Logging a Person object using this configuration will make log4php fall back to the newly 
				defined default renderer, which uses <code>var_dump</code> instead of <code>print_r</code>, and 
				the result will look like:</p>
						
<pre class="prettyprint linenums"><![CDATA[
INFO - Here comes the person:
class Person#5 (3) {
  public $firstName =>
  string(4) "John"
  public $lastName =>
  string(3) "Doe"
  public $age =>
  int(37)
}
]]></pre>
			</subsection>
			
			<subsection name="Class hierarchy">
				<p>Object rendering follows the class hierarchy. </p>

				<p>For example, if there is a class named Fruit, and classes Orange, Lemon and Apple all extend Fruit. 
				When FruitRenderer is registered as renderer for the Fruit class, all subclasses of Fruit will also 
				be rendered by FruitRenderer. Of course, it is possible to override this by registering OrangeRenderer 
				as renderer for the Orange class.</p>
			</subsection>
		</section>
	</body>
</document>
