You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ih...@apache.org on 2011/12/10 12:23:51 UTC
svn commit: r1212773 - in /logging/log4php/trunk/src: changes/changes.xml
main/php/LoggerLoggingEvent.php main/php/LoggerMDC.php
main/php/layouts/LoggerLayoutXml.php test/php/LoggerMDCTest.php
test/php/layouts/LoggerLayoutXmlTest.php
Author: ihabunek
Date: Sat Dec 10 11:23:50 2011
New Revision: 1212773
URL: http://svn.apache.org/viewvc?rev=1212773&view=rev
Log:
LOG4PHP-165: Extended LoggerLayoutXml to include MDC info
Modified:
logging/log4php/trunk/src/changes/changes.xml
logging/log4php/trunk/src/main/php/LoggerLoggingEvent.php
logging/log4php/trunk/src/main/php/LoggerMDC.php
logging/log4php/trunk/src/main/php/layouts/LoggerLayoutXml.php
logging/log4php/trunk/src/test/php/LoggerMDCTest.php
logging/log4php/trunk/src/test/php/layouts/LoggerLayoutXmlTest.php
Modified: logging/log4php/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/changes/changes.xml?rev=1212773&r1=1212772&r2=1212773&view=diff
==============================================================================
--- logging/log4php/trunk/src/changes/changes.xml (original)
+++ logging/log4php/trunk/src/changes/changes.xml Sat Dec 10 11:23:50 2011
@@ -21,6 +21,7 @@
</properties>
<body>
<release version="2.2.0" date="SVN">
+ <action date="2011-12-10" type="update" issue="LOG4PHP-165" dev="Ivan Habunek" due-to="Johannes Wohlgemuth" due-to-email="j dot wohlgemuth at findologic dot com">Extended LoggerLayoutXml to include MDC info</action>
<action date="2011-12-09" type="fix" issue="LOG4PHP-162" dev="Ivan Habunek">Warning for invalid appender threshold level never called.</action>
<action date="2011-12-08" type="fix" issue="LOG4PHP-114" dev="Ivan Habunek">Order of params in LoggerAppenderDailyFile configuration is significant.</action>
<action date="2011-12-08" type="update" issue="LOG4PHP-154" dev="Ivan Habunek">Rewritten LoggerAppenderSocket to use a layout.</action>
Modified: logging/log4php/trunk/src/main/php/LoggerLoggingEvent.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/main/php/LoggerLoggingEvent.php?rev=1212773&r1=1212772&r2=1212773&view=diff
==============================================================================
--- logging/log4php/trunk/src/main/php/LoggerLoggingEvent.php (original)
+++ logging/log4php/trunk/src/main/php/LoggerLoggingEvent.php Sat Dec 10 11:23:50 2011
@@ -272,6 +272,14 @@ class LoggerLoggingEvent {
public function getMDC($key) {
return LoggerMDC::get($key);
}
+
+ /**
+ * Returns the entire MDC context.
+ * @return array
+ */
+ public function getMDCMap () {
+ return LoggerMDC::getMap();
+ }
/**
* Render message.
Modified: logging/log4php/trunk/src/main/php/LoggerMDC.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/main/php/LoggerMDC.php?rev=1212773&r1=1212772&r2=1212773&view=diff
==============================================================================
--- logging/log4php/trunk/src/main/php/LoggerMDC.php (original)
+++ logging/log4php/trunk/src/main/php/LoggerMDC.php Sat Dec 10 11:23:50 2011
@@ -21,17 +21,15 @@
/**
* The LoggerMDC class provides <i>mapped diagnostic contexts</i>.
*
- * <p>A <i>Mapped Diagnostic Context</i>, or
+ * A <i>Mapped Diagnostic Context</i>, or
* MDC in short, is an instrument for distinguishing interleaved log
* output from different sources. Log output is typically interleaved
* when a server handles multiple clients near-simultaneously.
*
- * <p>This class is similar to the {@link LoggerNDC} class except that
+ * This class is similar to the {@link LoggerNDC} class except that
* it is based on a map instead of a stack.
*
- * <p><b>The MDC is managed on a per thread basis</b>.
- *
- * <p>Example:
+ * Example:
*
* {@example ../../examples/php/mdc.php 19}<br>
*
@@ -51,19 +49,12 @@
*/
class LoggerMDC {
- /**
- * This is the repository of user mappings
- */
+ /** Holds the context map. */
private static $map = array();
/**
- * Put a context value as identified with the key parameter into the current thread's
- * context map.
- *
- * <p>If the current thread does not have a context map it is
- * created as a side effect.</p>
- *
- * <p>Note that you cannot put more than {@link self::HT_SIZE} keys.</p>
+ * Stores a context value as identified with the key parameter into the
+ * context map.
*
* @param string $key the key
* @param string $value the value
@@ -73,17 +64,15 @@ class LoggerMDC {
}
/**
- * Get the context identified by the key parameter.
- *
- * <p>You can use special key identifiers to map values in
- * PHP $_SERVER and $_ENV vars. Just put a 'server.' or 'env.'
- * followed by the var name you want to refer.</p>
+ * Returns the context value identified by the key parameter.
*
- * <p>This method has no side effects.</p>
- *
- * @param string $key the key
- * @return string the context or an empty string if no context found
- * for given key
+ * Special key identifiers can be used to map values in the global $_SERVER
+ * and $_ENV vars. To access them, use 'server.' or 'env.' followed by the
+ * desired var name as the key.
+ *
+ * @param string $key The key.
+ * @return string The context or an empty string if no context found
+ * for given key.
*/
public static function get($key) {
if(!empty($key)) {
@@ -102,13 +91,28 @@ class LoggerMDC {
}
/**
- * Remove the the context identified by the key parameter.
+ * Returns the contex map as an array.
+ * @return array The MDC context map.
+ */
+ public static function getMap() {
+ return self::$map;
+ }
+
+ /**
+ * Removes the the context identified by the key parameter.
*
- * It only affects user mappings, not $_ENV or $_SERVER.
+ * Only affects user mappings, not $_ENV or $_SERVER.
*
- * @param string $key the key to be removed
+ * @param string $key The key to be removed.
*/
public static function remove($key) {
unset(self::$map[$key]);
}
+
+ /**
+ * Clears the mapped diagnostic context.
+ */
+ public static function clear() {
+ self::$map = array();
+ }
}
Modified: logging/log4php/trunk/src/main/php/layouts/LoggerLayoutXml.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/main/php/layouts/LoggerLayoutXml.php?rev=1212773&r1=1212772&r2=1212773&view=diff
==============================================================================
--- logging/log4php/trunk/src/main/php/layouts/LoggerLayoutXml.php (original)
+++ logging/log4php/trunk/src/main/php/layouts/LoggerLayoutXml.php Sat Dec 10 11:23:50 2011
@@ -63,43 +63,35 @@ class LoggerLayoutXml extends LoggerLayo
const CDATA_START = '<![CDATA[';
const CDATA_END = ']]>';
const CDATA_PSEUDO_END = ']]>';
-
const CDATA_EMBEDDED_END = ']]>]]><![CDATA[';
/**
* If set to true then the file name and line number of the origin of the
* log statement will be output.
- *
* @var boolean
*/
private $locationInfo = true;
/**
- * @var boolean set the elements namespace
+ * If set to true, log4j namespace will be used instead of the log4php
+ * namespace.
+ * @var boolean
*/
private $log4jNamespace = false;
+ /** The namespace in use. */
+ private $namespace = self::LOG4PHP_NS;
- /**
- * @var string namespace
- */
- private $_namespace = self::LOG4PHP_NS;
-
- /**
- * @var string namespace prefix
- */
- private $_namespacePrefix = self::LOG4PHP_NS_PREFIX;
+ /** The namespace prefix in use */
+ private $namespacePrefix = self::LOG4PHP_NS_PREFIX;
- /**
- * No options to activate.
- */
public function activateOptions() {
if ($this->getLog4jNamespace()) {
- $this->_namespace = self::LOG4J_NS;
- $this->_namespacePrefix = self::LOG4J_NS_PREFIX;
+ $this->namespace = self::LOG4J_NS;
+ $this->namespacePrefix = self::LOG4J_NS_PREFIX;
} else {
- $this->_namespace = self::LOG4PHP_NS;
- $this->_namespacePrefix = self::LOG4PHP_NS_PREFIX;
+ $this->namespace = self::LOG4PHP_NS;
+ $this->namespacePrefix = self::LOG4PHP_NS_PREFIX;
}
}
@@ -107,11 +99,11 @@ class LoggerLayoutXml extends LoggerLayo
* @return string
*/
public function getHeader() {
- return "<{$this->_namespacePrefix}:eventSet ".
- "xmlns:{$this->_namespacePrefix}=\"{$this->_namespace}\" ".
- "version=\"0.3\" ".
- "includesLocationInfo=\"".($this->getLocationInfo() ? "true" : "false")."\"".
- ">\r\n";
+ return "<{$this->namespacePrefix}:eventSet ".
+ "xmlns:{$this->namespacePrefix}=\"{$this->namespace}\" ".
+ "version=\"0.3\" ".
+ "includesLocationInfo=\"".($this->getLocationInfo() ? "true" : "false")."\"".
+ ">" . PHP_EOL;
}
/**
@@ -121,51 +113,59 @@ class LoggerLayoutXml extends LoggerLayo
* @return string
*/
public function format(LoggerLoggingEvent $event) {
+ $ns = $this->namespacePrefix;
+
$loggerName = $event->getLoggerName();
- $timeStamp = number_format((float)($event->getTimeStamp() * 1000), 0, '', '');
- $thread = $event->getThreadName();
- $level = $event->getLevel();
- $levelStr = $level->toString();
-
- $buf = "<{$this->_namespacePrefix}:event logger=\"{$loggerName}\" level=\"{$levelStr}\" thread=\"{$thread}\" timestamp=\"{$timeStamp}\">".PHP_EOL;
- $buf .= "<{$this->_namespacePrefix}:message><![CDATA[";
- $this->appendEscapingCDATA($buf, $event->getRenderedMessage());
- $buf .= "]]></{$this->_namespacePrefix}:message>".PHP_EOL;
+ $timeStamp = number_format((float)($event->getTimeStamp() * 1000), 0, '', '');
+ $thread = $event->getThreadName();
+ $level = $event->getLevel()->toString();
+
+ $buf = "<$ns:event logger=\"{$loggerName}\" level=\"{$level}\" thread=\"{$thread}\" timestamp=\"{$timeStamp}\">".PHP_EOL;
+ $buf .= "<$ns:message>";
+ $buf .= $this->encodeCDATA($event->getRenderedMessage());
+ $buf .= "</$ns:message>".PHP_EOL;
$ndc = $event->getNDC();
- if($ndc != null) {
- $buf .= "<{$this->_namespacePrefix}:NDC><![CDATA[";
- $this->appendEscapingCDATA($buf, $ndc);
- $buf .= "]]></{$this->_namespacePrefix}:NDC>".PHP_EOL;
+ if(!empty($ndc)) {
+ $buf .= "<$ns:NDC><![CDATA[";
+ $buf .= $this->encodeCDATA($ndc);
+ $buf .= "]]></$ns:NDC>".PHP_EOL;
+ }
+
+ $mdcMap = $event->getMDCMap();
+ if (!empty($mdcMap)) {
+ $buf .= "<$ns:properties>".PHP_EOL;
+ foreach ($mdcMap as $name=>$value) {
+ $buf .= "<$ns:data name=\"$name\" value=\"$value\" />".PHP_EOL;
+ }
+ $buf .= "</$ns:properties>".PHP_EOL;
}
if ($this->getLocationInfo()) {
$locationInfo = $event->getLocationInformation();
- $buf .= "<{$this->_namespacePrefix}:locationInfo ".
+ $buf .= "<$ns:locationInfo ".
"class=\"" . $locationInfo->getClassName() . "\" ".
"file=\"" . htmlentities($locationInfo->getFileName(), ENT_QUOTES) . "\" ".
"line=\"" . $locationInfo->getLineNumber() . "\" ".
"method=\"" . $locationInfo->getMethodName() . "\" ";
$buf .= "/>".PHP_EOL;
-
}
- $buf .= "</{$this->_namespacePrefix}:event>".PHP_EOL.PHP_EOL;
+ $buf .= "</$ns:event>".PHP_EOL;
return $buf;
-
}
/**
* @return string
*/
public function getFooter() {
- return "</{$this->_namespacePrefix}:eventSet>\r\n";
+ return "</{$this->namespacePrefix}:eventSet>" . PHP_EOL;
}
- /** Whether or not file name and line number will be included in the output.
- *
+ /**
+ * Whether or not file name and line number will be included in the output.
* @return boolean
*/
public function getLocationInfo() {
@@ -197,28 +197,14 @@ class LoggerLayoutXml extends LoggerLayo
$this->log4jNamespace = LoggerOptionConverter::toBoolean($flag, true);
}
- /**
- * Ensures that embeded CDEnd strings (]]>) are handled properly
- * within message, NDC and throwable tag text.
- *
- * @param string $buf String holding the XML data to this point. The
- * initial CDStart (<![CDATA[) and final CDEnd (]]>)
- * of the CDATA section are the responsibility of
- * the calling method.
- * @param string str The String that is inserted into an existing
- * CDATA Section within buf.
- */
- private function appendEscapingCDATA(&$buf, $str) {
- if(empty($str)) {
- return;
- }
-
- $rStr = str_replace(
- self::CDATA_END,
- self::CDATA_EMBEDDED_END,
- $str
- );
- $buf .= $rStr;
+ /**
+ * Encases a string in CDATA tags, and escapes any existing CDATA end
+ * tags already present in the string.
+ * @param string $string
+ */
+ private function encodeCDATA($string) {
+ $string = str_replace(self::CDATA_END, self::CDATA_EMBEDDED_END, $string);
+ return self::CDATA_START . $string . self::CDATA_END;
}
}
Modified: logging/log4php/trunk/src/test/php/LoggerMDCTest.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/test/php/LoggerMDCTest.php?rev=1212773&r1=1212772&r2=1212773&view=diff
==============================================================================
--- logging/log4php/trunk/src/test/php/LoggerMDCTest.php (original)
+++ logging/log4php/trunk/src/test/php/LoggerMDCTest.php Sat Dec 10 11:23:50 2011
@@ -52,7 +52,14 @@ class LoggerMDCTest extends PHPUnit_Fram
*/
private $patternServer = "%-5p %c: %X{server.PHP_SELF} %m";
-
+ protected function setUp() {
+ LoggerMDC::clear();
+ }
+
+ protected function tearDown() {
+ LoggerMDC::clear();
+ }
+
public function testPatterns() {
// Create some data to test with
@@ -60,6 +67,15 @@ class LoggerMDCTest extends PHPUnit_Fram
LoggerMDC::put('key2', 'valueofkey2');
LoggerMDC::put(3, 'valueofkey3');
+ $expected = array(
+ 'key1' => 'valueofkey1',
+ 'key2' => 'valueofkey2',
+ 3 => 'valueofkey3',
+ );
+ $actual = LoggerMDC::getMap();
+
+ self::assertSame($expected, $actual);
+
$event = new LoggerLoggingEvent("LoggerLayoutPattern", new Logger("TEST"), LoggerLevel::getLevelInfo(), "Test message");
// Pattern with 1 key
Modified: logging/log4php/trunk/src/test/php/layouts/LoggerLayoutXmlTest.php
URL: http://svn.apache.org/viewvc/logging/log4php/trunk/src/test/php/layouts/LoggerLayoutXmlTest.php?rev=1212773&r1=1212772&r2=1212773&view=diff
==============================================================================
--- logging/log4php/trunk/src/test/php/layouts/LoggerLayoutXmlTest.php (original)
+++ logging/log4php/trunk/src/test/php/layouts/LoggerLayoutXmlTest.php Sat Dec 10 11:23:50 2011
@@ -19,7 +19,7 @@
* @package log4php
* @subpackage appenders
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
- * @version SVN: $Id$
+ * @version $Revision$
* @link http://logging.apache.org/log4php
*/
@@ -27,55 +27,122 @@
* @group layouts
*/
class LoggerLayoutXmlTest extends PHPUnit_Framework_TestCase {
-
+
public function testErrorLayout() {
- $event = new LoggerLoggingEvent("LoggerLayoutXml", new Logger("TEST"), LoggerLevel::getLevelError(), "testmessage");
+ $event = LoggerTestHelper::getErrorEvent("testmessage");
$layout = new LoggerLayoutXml();
- $v = $layout->format($event);
+ $layout->activateOptions();
+
+ $actual = $layout->format($event);
- $e = "<log4php:event logger=\"TEST\" level=\"ERROR\" thread=\"".$event->getThreadName().
- "\" timestamp=\"".number_format((float)($event->getTimeStamp() * 1000), 0, '', '')."\">".PHP_EOL.
- "<log4php:message><![CDATA[testmessage]]></log4php:message>".PHP_EOL.
- "<log4php:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
- "method=\"getLocationInformation\" />".PHP_EOL.
- "</log4php:event>".PHP_EOL . PHP_EOL;
-
- self::assertEquals($v, $e);
- }
-
- public function testWarnLayout() {
- $event = new LoggerLoggingEvent("LoggerLayoutXml", new Logger("TEST"), LoggerLevel::getLevelWarn(), "testmessage");
+ $thread = $event->getThreadName();
+ $timestamp = number_format(($event->getTimeStamp() * 1000), 0, '', '');
+
+ $expected = "<log4php:event logger=\"test\" level=\"ERROR\" thread=\"$thread\" timestamp=\"$timestamp\">" . PHP_EOL .
+ "<log4php:message><![CDATA[testmessage]]></log4php:message>" . PHP_EOL .
+ "<log4php:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
+ "method=\"getLocationInformation\" />" . PHP_EOL .
+ "</log4php:event>" . PHP_EOL;
+
+ self::assertEquals($expected, $actual);
+ }
+
+ public function testWarnLayout() {
+ $event = LoggerTestHelper::getWarnEvent("testmessage");
$layout = new LoggerLayoutXml();
- $v = $layout->format($event);
+ $layout->activateOptions();
+
+ $actual = $layout->format($event);
- $e = "<log4php:event logger=\"TEST\" level=\"WARN\" thread=\"".$event->getThreadName().
- "\" timestamp=\"".number_format((float)($event->getTimeStamp() * 1000), 0, '', '')."\">".PHP_EOL.
- "<log4php:message><![CDATA[testmessage]]></log4php:message>".PHP_EOL.
- "<log4php:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
- "method=\"getLocationInformation\" />".PHP_EOL.
- "</log4php:event>".PHP_EOL . PHP_EOL;
-
- self::assertEquals($v, $e);
- }
-
- public function testLog4JNamespaceErrorLayout() {
- $event = new LoggerLoggingEvent("LoggerLayoutXml", new Logger("TEST"), LoggerLevel::getLevelError(), "testmessage");
+ $thread = $event->getThreadName();
+ $timestamp = number_format(($event->getTimeStamp() * 1000), 0, '', '');
+
+ $expected = "<log4php:event logger=\"test\" level=\"WARN\" thread=\"$thread\" timestamp=\"$timestamp\">" . PHP_EOL .
+ "<log4php:message><![CDATA[testmessage]]></log4php:message>" . PHP_EOL .
+ "<log4php:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
+ "method=\"getLocationInformation\" />" . PHP_EOL .
+ "</log4php:event>" . PHP_EOL;
+
+ self::assertEquals($expected, $actual);
+ }
+
+ public function testLog4JNamespaceErrorLayout() {
+ $event = LoggerTestHelper::getErrorEvent("testmessage");
$layout = new LoggerLayoutXml();
$layout->setLog4jNamespace(true);
$layout->activateOptions();
- $v = $layout->format($event);
+ $actual = $layout->format($event);
- $e = "<log4j:event logger=\"TEST\" level=\"ERROR\" thread=\"".$event->getThreadName().
- "\" timestamp=\"".number_format((float)($event->getTimeStamp() * 1000), 0, '', '')."\">".PHP_EOL.
- "<log4j:message><![CDATA[testmessage]]></log4j:message>".PHP_EOL.
- "<log4j:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
- "method=\"getLocationInformation\" />".PHP_EOL.
- "</log4j:event>".PHP_EOL . PHP_EOL;
+ $thread = $event->getThreadName();
+ $timestamp = number_format(($event->getTimeStamp() * 1000), 0, '', '');
+
+ $expected = "<log4j:event logger=\"test\" level=\"ERROR\" thread=\"$thread\" timestamp=\"$timestamp\">" . PHP_EOL .
+ "<log4j:message><![CDATA[testmessage]]></log4j:message>" . PHP_EOL .
+ "<log4j:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
+ "method=\"getLocationInformation\" />" . PHP_EOL .
+ "</log4j:event>" . PHP_EOL;
+
+ self::assertEquals($expected, $actual);
+ }
+
+ public function testNDC()
+ {
+ LoggerNDC::push('foo');
+ LoggerNDC::push('bar');
+
+ $event = LoggerTestHelper::getErrorEvent("testmessage");
+
+ $layout = new LoggerLayoutXml();
+ $layout->activateOptions();
+
+ $actual = $layout->format($event);
- self::assertEquals($v, $e);
- }
+ $thread = $event->getThreadName();
+ $timestamp = number_format(($event->getTimeStamp() * 1000), 0, '', '');
+
+ $expected = "<log4php:event logger=\"test\" level=\"ERROR\" thread=\"$thread\" timestamp=\"$timestamp\">" . PHP_EOL .
+ "<log4php:message><![CDATA[testmessage]]></log4php:message>" . PHP_EOL .
+ "<log4php:NDC><![CDATA[<![CDATA[foo bar]]>]]></log4php:NDC>" . PHP_EOL .
+ "<log4php:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
+ "method=\"getLocationInformation\" />" . PHP_EOL .
+ "</log4php:event>" . PHP_EOL;
+
+ self::assertEquals($expected, $actual);
+
+ LoggerNDC::clear();
+ }
+
+ public function testMDC()
+ {
+ LoggerMDC::put('foo', 'bar');
+ LoggerMDC::put('bla', 'tra');
+
+ $event = LoggerTestHelper::getErrorEvent("testmessage");
+
+ $layout = new LoggerLayoutXml();
+ $layout->activateOptions();
+
+ $actual = $layout->format($event);
+
+ $thread = $event->getThreadName();
+ $timestamp = number_format(($event->getTimeStamp() * 1000), 0, '', '');
+
+ $expected = "<log4php:event logger=\"test\" level=\"ERROR\" thread=\"$thread\" timestamp=\"$timestamp\">" . PHP_EOL .
+ "<log4php:message><![CDATA[testmessage]]></log4php:message>" . PHP_EOL .
+ "<log4php:properties>" . PHP_EOL .
+ "<log4php:data name=\"foo\" value=\"bar\" />" . PHP_EOL .
+ "<log4php:data name=\"bla\" value=\"tra\" />" . PHP_EOL .
+ "</log4php:properties>" . PHP_EOL .
+ "<log4php:locationInfo class=\"LoggerLoggingEvent\" file=\"NA\" line=\"NA\" " .
+ "method=\"getLocationInformation\" />" . PHP_EOL .
+ "</log4php:event>" . PHP_EOL;
+
+ self::assertEquals($expected, $actual);
+
+ LoggerMDC::clear();
+ }
}