| <?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>Loggers</title> | |
| </properties> | |
| <body> | |
| <section name="Loggers"> | |
| <p>A logger is a component which will take your logging request and log it. Each class in a project can | |
| have an individual logger, or they can all use a common logger. Loggers are named entities; it is | |
| common to name them after the class which will use it for logging.</p> | |
| <p>Creating a logger is done by calling the static <code>getLogger()</code> method on the Logger object | |
| and providing the name of the logger. For example, to create a logger named <code>foo</code>:</p> | |
| <pre class="prettyprint">$logger = Logger::getLogger('foo');</pre> | |
| <p>Logging requests are made by invoking one of the printing methods of a Logger instance. These logging | |
| methods are: trace, debug, info, warn, error and fatal. The printing method determines the level of a | |
| logging request. For example, calling the method <code>info()</code> creates a logging request of level | |
| <code>INFO</code>. For example:</p> | |
| <pre class="prettyprint">$logger->info("This is the message to be logged.");</pre> | |
| <p>Loggers by themselves do not define where these messages will be logged. For that you need to assign | |
| one or more <a href="./appenders.html">appenders</a> to the logger.</p> | |
| <subsection name="Logger threshold" id="Logger_threshold"> | |
| <p>A logger can be assigned a threshold level. All logging requests with level lower than this threshold | |
| will be ignored.</p> | |
| <p>For example, setting logger threshold to <code>INFO</code> means that logging requests with levels | |
| <code>TRACE</code> and <code>DEBUG</code> will not be logged by this logger.</p> | |
| <p>An example of setting the root logger threshold to <code>INFO</code>:</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| <configuration xmlns="http://logging.apache.org/log4php/"> | |
| <appender name="default" class="LoggerAppenderConsole" /> | |
| <root> | |
| <level value="info" /> | |
| <appender_ref ref="default" /> | |
| </root> | |
| </configuration> | |
| ]]></pre> | |
| <p>If not explicitly configured, loggers will have their threshold level set to <code>DEBUG</code> by | |
| default.</p> | |
| </subsection> | |
| <subsection name="Configuring loggers" id="Configuring_loggers"> | |
| <p>Loggers can be individually configured in the configuration file. </p> | |
| <p>The simplest example is to configure the root logger, since all other loggers will inherit its | |
| settings, as explained in the <a href="#Logger_hierarchy">next section</a>.</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| <configuration xmlns="http://logging.apache.org/log4php/"> | |
| <appender name="default" class="LoggerAppenderConsole" /> | |
| <root> | |
| <level value="info" /> | |
| <appender_ref ref="default" /> | |
| </root> | |
| </configuration> | |
| ]]></pre> | |
| <p>This configuration adds the <code>default</code> appender to the root logger, and sets it's | |
| <a href="#Logger_threshold">threshold level</a> to <code>INFO</code>.</p> | |
| <p>It is also possible to configure individual named loggers. For example, let's configure the | |
| <code>foo</code> logger, used in the example above, and set it's threshold to WARN:</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| <configuration xmlns="http://logging.apache.org/log4php/"> | |
| <appender name="default" class="LoggerAppenderConsole" /> | |
| <logger name="foo"> | |
| <level value="warn" /> | |
| <appender_ref ref="default" /> | |
| </logger> | |
| </configuration> | |
| ]]></pre> | |
| </subsection> | |
| <subsection name="Logger hierarchy" id="Logger_hierarchy"> | |
| <p>Loggers follow a parent-child relationship pattern which is implemented by using a naming pattern. | |
| A logger is said to be an <em>ancestor</em> of another logger if its name followed by a dot is a | |
| prefix of the <em>descendant</em> logger name. A logger is said to be a <em>parent</em> of a | |
| <em>child</em> logger if there are no ancestors between itself and the descendant logger.</p> | |
| <p>For example, the logger named <code>foo</code> is a parent of the logger named <code>foo.bar</code>. | |
| Similarly, <code>org</code> is a parent of <code>org.apache</code> and an ancestor of | |
| <code>org.apache.logging</code>. This naming scheme should be familiar to most developers.</p> | |
| <p>The root logger resides at the top of the logger hierarchy. It is exceptional in two ways:</p> | |
| <ul> | |
| <li>it always exists,</li> | |
| <li>it cannot be retrieved by name.</li> | |
| </ul> | |
| <p>Invoking the class static <code>Logger::getRootLogger()</code> method retrieves the root logger. | |
| All other loggers are instantiated and retrieved with the <code>Logger::getLogger($name)</code> | |
| method. This method takes the name of the desired logger as a parameter. If the logger does not exist | |
| at the time of the call, it will be created.</p> | |
| </subsection> | |
| <subsection name="Logger inheritance" id="Logger_inheritance"> | |
| <p>The threshold level and appenders are inherited from the parent to the child loggers.</p> | |
| <p>For example examine the following configuration:</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| <configuration xmlns="http://logging.apache.org/log4php/"> | |
| <appender name="default" class="LoggerAppenderConsole" /> | |
| <root> | |
| <level value="debug" /> | |
| <appender_ref ref="default" /> | |
| </root> | |
| </configuration> | |
| ]]></pre> | |
| <p>The threshold level of the root logger is set to debug. Also, the root logger is linked to a console | |
| appender. Any named logger that is created will inherit these root settings.</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| $main = Logger::getLogger('main'); | |
| $main->trace('This will not be logged.'); | |
| $main->info('This will be logged.'); | |
| ]]></pre> | |
| <p>A logger named <code>main</code> is created. Since there is no logger-specific configuration, it | |
| will inherit all of it's settings from the root logger: a console appender, and threshold set to DEBUG. | |
| Therefore, this code will produce the following output:</p> | |
| <pre>INFO - This will be logged.</pre> | |
| </subsection> | |
| <subsection name="Appender additivity" id="Appender_additivity"> | |
| <p>Appender additivity is a property of loggers to inherit their parent's appenders. By default all | |
| loggers have appender additivity enabled.</p> | |
| <p>Let's take the following example:</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| <configuration xmlns="http://logging.apache.org/log4php/"> | |
| <appender name="A1" class="LoggerAppenderConsole" /> | |
| <appender name="A2" class="LoggerAppenderConsole" /> | |
| <root> | |
| <appender_ref ref="A1" /> | |
| </root> | |
| <logger name="foo"> | |
| <appender_ref ref="A2" /> | |
| </logger> | |
| </configuration> | |
| ]]></pre> | |
| <p>Since additivity is enabled by default, the logger <code>foo</code> will have two linked appenders: | |
| A1 which it will inherit from the root logger, and A2 which is defined for it specifically.</p> | |
| <p>Therefore, by executing the following code:</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| $main = Logger::getLogger('foo'); | |
| $main->info('This will be logged twice.'); | |
| ]]></pre> | |
| <p>The message will be logged twice - once by A1 and once by A2, producing:</p> | |
| <pre> | |
| INFO - This will be logged twice. | |
| INFO - This will be logged twice. | |
| </pre> | |
| <h4>Disabling appender additivity</h4> | |
| <p>Logger's appender additivity can also be disabled if needed.</p> | |
| <p>If the <code>foo</code> logger in the previous example was configured like this:</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| <logger name="foo" additivity="false"> | |
| <appender_ref ref="A2" /> | |
| </logger> | |
| ]]></pre> | |
| <p>Then the logger would not have inherited the A1 appender from the root logger, and the message | |
| would have been logged only once.</p> | |
| <h4>A more complex example</h4> | |
| <p>In this example we will look at multiple loggers making a hierarchy.</p> | |
| <p>Not to make the example too complex, all appenders will log to the console. Of course, this doesn't | |
| always have to be the case.</p> | |
| <p>Let's take the following configuration file:</p> | |
| <pre class="prettyprint linenums"><![CDATA[ | |
| <configuration xmlns="http://logging.apache.org/log4php/"> | |
| <appender name="A1" class="LoggerAppenderConsole" /> | |
| <appender name="A2" class="LoggerAppenderConsole" /> | |
| <appender name="A3" class="LoggerAppenderConsole" /> | |
| <appender name="A4" class="LoggerAppenderConsole" /> | |
| <root> | |
| <appender_ref ref="A1" /> | |
| </root> | |
| <logger name="foo"> | |
| <appender_ref ref="A2" /> | |
| <appender_ref ref="A3" /> | |
| </logger> | |
| <logger name="foo.bar" /> | |
| <logger name="foo.bar.baz" additivity="false"> | |
| <appender_ref ref="A4" /> | |
| </logger> | |
| </configuration> | |
| ]]></pre> | |
| <p>The table below shows how the configuration is interpreted, and which appenders are inherited:</p> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Logger name</th> | |
| <th>Linked appenders</th> | |
| <th>Additivity flag</th> | |
| <th>Output targets</th> | |
| <th>Comment</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td>root</td> | |
| <td>A1</td> | |
| <td>N/A</td> | |
| <td>A1</td> | |
| <td>One appender, named A1, is added to root logger. Any logging requests to root logger | |
| will be forwarded only to that one appender.</td> | |
| </tr> | |
| <tr> | |
| <td>foo</td> | |
| <td>A2, A3</td> | |
| <td>true</td> | |
| <td>A1, A2, A3</td> | |
| <td>A logger named <code>foo</code> is created and two appenders, named A2 and A3, are | |
| added to it. Additionally, because of logger additivity, <code>foo</code> inherits the | |
| appender A1 from the root logger which is it's parent in the logger hierarchy. Therefore | |
| logging requests to this logger will be forwarded to appenders A1, A2 and A3.</td> | |
| </tr> | |
| <tr> | |
| <td>foo.bar</td> | |
| <td>none</td> | |
| <td>true</td> | |
| <td>A1, A2, A3</td> | |
| <td>A logger named <code>foo.bar</code> is created. Because it's name starts with | |
| <code>foo</code>, it will be created as a child of the <code>foo</code> logger. | |
| No appenders are added to <code>foo.bar</code> but it will inherit it's ancestor's | |
| appenders: appenders A2 and A3 from <code>foo</code> and A1 from <code>root</code>. | |
| Logging requests to this logger will be forwarded to appenders A1, A2 and A3.</td> | |
| </tr> | |
| <tr> | |
| <td>foo.bar.baz</td> | |
| <td>A4</td> | |
| <td>false</td> | |
| <td>A4</td> | |
| <td>Finally, logger <code>foo.bar.baz</code> is created, and because of it's name it is | |
| created as child to <code>foo.bar</code>. One appender, A4 is added to it. However, since | |
| it's additivity flag is set to <em>false</em>, it will not inherit any appenders from it's | |
| ancestors. Logging requests to this logger will be forwarded only to appender A4.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </subsection> | |
| </section> | |
| </body> | |
| </document> |