library/log4php/layouts/LoggerLayoutXml.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 <?php
       
     2 /**
       
     3  * Licensed to the Apache Software Foundation (ASF) under one or more
       
     4  * contributor license agreements.  See the NOTICE file distributed with
       
     5  * this work for additional information regarding copyright ownership.
       
     6  * The ASF licenses this file to You under the Apache License, Version 2.0
       
     7  * (the "License"); you may not use this file except in compliance with
       
     8  * the License.  You may obtain a copy of the License at
       
     9  *
       
    10  *     http://www.apache.org/licenses/LICENSE-2.0
       
    11  *
       
    12  * Unless required by applicable law or agreed to in writing, software
       
    13  * distributed under the License is distributed on an "AS IS" BASIS,
       
    14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    15  * See the License for the specific language governing permissions and
       
    16  * limitations under the License.
       
    17  *
       
    18  * @package log4php
       
    19  */
       
    20 
       
    21 /**
       
    22  * The output of the LoggerXmlLayout consists of a series of log4php:event elements.
       
    23  *
       
    24  * Configurable parameters:
       
    25  * - {@link $locationInfo} - If set to true then the file name and line number
       
    26  *   of the origin of the log statement will be included in output.
       
    27  * - {@link $log4jNamespace} - If set to true then log4j namespace will be used
       
    28  *   instead of log4php namespace. This can be usefull when using log viewers
       
    29  *   which can only parse the log4j namespace such as Apache Chainsaw.
       
    30  *
       
    31  * <p>It does not output a complete well-formed XML file.
       
    32  * The output is designed to be included as an external entity in a separate file to form
       
    33  * a correct XML file.</p>
       
    34  *
       
    35  * Example:
       
    36  *
       
    37  * {@example ../../examples/php/layout_xml.php 19}<br>
       
    38  *
       
    39  * {@example ../../examples/resources/layout_xml.properties 18}<br>
       
    40  *
       
    41  * The above would print:
       
    42  *
       
    43  * <pre>
       
    44  * <log4php:eventSet xmlns:log4php="http://logging.apache.org/log4php/" version="0.3" includesLocationInfo="true">
       
    45  *    <log4php:event logger="root" level="INFO" thread="13802" timestamp="1252456226491">
       
    46  *        <log4php:message><![CDATA[Hello World!]]></log4php:message>
       
    47  *        <log4php:locationInfo class="main" file="examples/php/layout_xml.php" line="6" method="main" />
       
    48  *    </log4php:event>
       
    49  * </log4php:eventSet>
       
    50  * </pre>
       
    51  *
       
    52  * @version $Revision: 1213283 $
       
    53  * @package log4php
       
    54  * @subpackage layouts
       
    55  */
       
    56 class LoggerLayoutXml extends LoggerLayout {
       
    57     const LOG4J_NS_PREFIX = 'log4j';
       
    58     const LOG4J_NS = 'http://jakarta.apache.org/log4j/';
       
    59 
       
    60     const LOG4PHP_NS_PREFIX = 'log4php';
       
    61     const LOG4PHP_NS = 'http://logging.apache.org/log4php/';
       
    62 
       
    63     const CDATA_START = '<![CDATA[';
       
    64     const CDATA_END = ']]>';
       
    65     const CDATA_PSEUDO_END = ']]&gt;';
       
    66     const CDATA_EMBEDDED_END = ']]>]]&gt;<![CDATA[';
       
    67 
       
    68     /**
       
    69      * If set to true then the file name and line number of the origin of the
       
    70      * log statement will be output.
       
    71      * @var boolean
       
    72      */
       
    73     protected $locationInfo = true;
       
    74 
       
    75     /**
       
    76      * If set to true, log4j namespace will be used instead of the log4php
       
    77      * namespace.
       
    78      * @var boolean
       
    79      */
       
    80     protected $log4jNamespace = false;
       
    81 
       
    82     /** The namespace in use. */
       
    83     protected $namespace = self::LOG4PHP_NS;
       
    84 
       
    85     /** The namespace prefix in use */
       
    86     protected $namespacePrefix = self::LOG4PHP_NS_PREFIX;
       
    87 
       
    88     public function activateOptions() {
       
    89         if ($this->getLog4jNamespace()) {
       
    90             $this->namespace = self::LOG4J_NS;
       
    91             $this->namespacePrefix = self::LOG4J_NS_PREFIX;
       
    92         } else {
       
    93             $this->namespace = self::LOG4PHP_NS;
       
    94             $this->namespacePrefix = self::LOG4PHP_NS_PREFIX;
       
    95         }
       
    96     }
       
    97 
       
    98     /**
       
    99      * @return string
       
   100      */
       
   101     public function getHeader() {
       
   102         return "<{$this->namespacePrefix}:eventSet " .
       
   103         "xmlns:{$this->namespacePrefix}=\"{$this->namespace}\" " .
       
   104         "version=\"0.3\" " .
       
   105         "includesLocationInfo=\"" . ($this->getLocationInfo() ? "true" : "false") . "\"" .
       
   106         ">" . PHP_EOL;
       
   107     }
       
   108 
       
   109     /**
       
   110      * Formats a {@link LoggerLoggingEvent} in conformance with the log4php.dtd.
       
   111      *
       
   112      * @param LoggerLoggingEvent $event
       
   113      * @return string
       
   114      */
       
   115     public function format(LoggerLoggingEvent $event) {
       
   116         $ns = $this->namespacePrefix;
       
   117 
       
   118         $loggerName = $event->getLoggerName();
       
   119         $timeStamp = number_format((float)($event->getTimeStamp() * 1000), 0, '', '');
       
   120         $thread = $event->getThreadName();
       
   121         $level = $event->getLevel()->toString();
       
   122 
       
   123         $buf = "<$ns:event logger=\"{$loggerName}\" level=\"{$level}\" thread=\"{$thread}\" timestamp=\"{$timeStamp}\">" . PHP_EOL;
       
   124         $buf .= "<$ns:message>";
       
   125         $buf .= $this->encodeCDATA($event->getRenderedMessage());
       
   126         $buf .= "</$ns:message>" . PHP_EOL;
       
   127 
       
   128         $ndc = $event->getNDC();
       
   129         if (!empty($ndc)) {
       
   130             $buf .= "<$ns:NDC><![CDATA[";
       
   131             $buf .= $this->encodeCDATA($ndc);
       
   132             $buf .= "]]></$ns:NDC>" . PHP_EOL;
       
   133         }
       
   134 
       
   135         $mdcMap = $event->getMDCMap();
       
   136         if (!empty($mdcMap)) {
       
   137             $buf .= "<$ns:properties>" . PHP_EOL;
       
   138             foreach ($mdcMap as $name => $value) {
       
   139                 $buf .= "<$ns:data name=\"$name\" value=\"$value\" />" . PHP_EOL;
       
   140             }
       
   141             $buf .= "</$ns:properties>" . PHP_EOL;
       
   142         }
       
   143 
       
   144         if ($this->getLocationInfo()) {
       
   145             $locationInfo = $event->getLocationInformation();
       
   146             $buf .= "<$ns:locationInfo " .
       
   147                 "class=\"" . $locationInfo->getClassName() . "\" " .
       
   148                 "file=\"" . htmlentities($locationInfo->getFileName(), ENT_QUOTES) . "\" " .
       
   149                 "line=\"" . $locationInfo->getLineNumber() . "\" " .
       
   150                 "method=\"" . $locationInfo->getMethodName() . "\" ";
       
   151             $buf .= "/>" . PHP_EOL;
       
   152         }
       
   153 
       
   154         $buf .= "</$ns:event>" . PHP_EOL;
       
   155 
       
   156         return $buf;
       
   157     }
       
   158 
       
   159     /**
       
   160      * @return string
       
   161      */
       
   162     public function getFooter() {
       
   163         return "</{$this->namespacePrefix}:eventSet>" . PHP_EOL;
       
   164     }
       
   165 
       
   166 
       
   167     /**
       
   168      * Whether or not file name and line number will be included in the output.
       
   169      * @return boolean
       
   170      */
       
   171     public function getLocationInfo() {
       
   172         return $this->locationInfo;
       
   173     }
       
   174 
       
   175     /**
       
   176      * The {@link $locationInfo} option takes a boolean value. By default,
       
   177      * it is set to false which means there will be no location
       
   178      * information output by this layout. If the the option is set to
       
   179      * true, then the file name and line number of the statement at the
       
   180      * origin of the log statement will be output.
       
   181      */
       
   182     public function setLocationInfo($flag) {
       
   183         $this->setBoolean('locationInfo', $flag);
       
   184     }
       
   185 
       
   186     /**
       
   187      * @return boolean
       
   188      */
       
   189     public function getLog4jNamespace() {
       
   190         return $this->log4jNamespace;
       
   191     }
       
   192 
       
   193     /**
       
   194      * @param boolean
       
   195      */
       
   196     public function setLog4jNamespace($flag) {
       
   197         $this->setBoolean('log4jNamespace', $flag);
       
   198     }
       
   199 
       
   200     /**
       
   201      * Encases a string in CDATA tags, and escapes any existing CDATA end
       
   202      * tags already present in the string.
       
   203      * @param string $string
       
   204      */
       
   205     private function encodeCDATA($string) {
       
   206         $string = str_replace(self::CDATA_END, self::CDATA_EMBEDDED_END, $string);
       
   207         return self::CDATA_START . $string . self::CDATA_END;
       
   208     }
       
   209 }
       
   210