PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/apache-log4php/trunk/src/main/php/LoggerNDC.php

http://owasp-esapi-php.googlecode.com/
PHP | 201 lines | 45 code | 11 blank | 145 comment | 7 complexity | 28e7cfc8055590383fc881e63a7b734e MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  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. */
  19. /**
  20. * This is the global repository of NDC stack
  21. */
  22. $GLOBALS['log4php.LoggerNDC.ht'] = array();
  23. /**
  24. * The NDC class implements <i>nested diagnostic contexts</i> as
  25. * defined by Neil Harrison in the article "Patterns for Logging
  26. * Diagnostic Messages" part of the book "<i>Pattern Languages of
  27. * Program Design 3</i>" edited by Martin et al.
  28. *
  29. * <p>A Nested Diagnostic Context, or NDC in short, is an instrument
  30. * to distinguish interleaved log output from different sources. Log
  31. * output is typically interleaved when a server handles multiple
  32. * clients near-simultaneously.
  33. *
  34. * <p>Interleaved log output can still be meaningful if each log entry
  35. * from different contexts had a distinctive stamp. This is where NDCs
  36. * come into play.
  37. *
  38. * <p><i><b>Note that NDCs are managed on a per thread
  39. * basis</b></i>. NDC operations such as {@link push()}, {@link pop()},
  40. * {@link clear()}, {@link getDepth()} and {@link setMaxDepth()}
  41. * affect the NDC of the <i>current</i> thread only. NDCs of other
  42. * threads remain unaffected.
  43. *
  44. * <p>For example, a servlet can build a per client request NDC
  45. * consisting the clients host name and other information contained in
  46. * the the request. <i>Cookies</i> are another source of distinctive
  47. * information. To build an NDC one uses the {@link push()}
  48. * operation.</p>
  49. *
  50. * Simply put,
  51. *
  52. * - Contexts can be nested.
  53. * - When entering a context, call
  54. * <code>LoggerNDC::push()</code>
  55. * As a side effect, if there is no nested diagnostic context for the
  56. * current thread, this method will create it.
  57. * - When leaving a context, call
  58. * <code>LoggerNDC::pop()</code>
  59. * - <b>When exiting a thread make sure to call {@link remove()}</b>
  60. *
  61. * <p>There is no penalty for forgetting to match each
  62. * <code>push</code> operation with a corresponding <code>pop</code>,
  63. * except the obvious mismatch between the real application context
  64. * and the context set in the NDC.</p>
  65. *
  66. * <p>If configured to do so, {@link LoggerPatternLayout} and {@link LoggerLayoutTTCC}
  67. * instances automatically retrieve the nested diagnostic
  68. * context for the current thread without any user intervention.
  69. * Hence, even if a servlet is serving multiple clients
  70. * simultaneously, the logs emanating from the same code (belonging to
  71. * the same category) can still be distinguished because each client
  72. * request will have a different NDC tag.</p>
  73. *
  74. *
  75. * @version $Revision: 795643 $
  76. * @package log4php
  77. * @since 0.3
  78. */
  79. class LoggerNDC {
  80. const HT_SIZE = 7;
  81. /**
  82. * Clear any nested diagnostic information if any. This method is
  83. * useful in cases where the same thread can be potentially used
  84. * over and over in different unrelated contexts.
  85. *
  86. * <p>This method is equivalent to calling the {@link setMaxDepth()}
  87. * method with a zero <var>maxDepth</var> argument.
  88. *
  89. * @static
  90. */
  91. public static function clear() {
  92. $GLOBALS['log4php.LoggerNDC.ht'] = array();
  93. }
  94. /**
  95. * Never use this method directly, use the {@link LoggerLoggingEvent::getNDC()} method instead.
  96. * @static
  97. * @return array
  98. */
  99. public static function get() {
  100. if(!array_key_exists('log4php.LoggerNDC.ht', $GLOBALS)) {
  101. LoggerNDC::clear();
  102. }
  103. return $GLOBALS['log4php.LoggerNDC.ht'];
  104. }
  105. /**
  106. * Get the current nesting depth of this diagnostic context.
  107. *
  108. * @see setMaxDepth()
  109. * @return integer
  110. * @static
  111. */
  112. public static function getDepth() {
  113. return count($GLOBALS['log4php.LoggerNDC.ht']);
  114. }
  115. /**
  116. * Clients should call this method before leaving a diagnostic
  117. * context.
  118. *
  119. * <p>The returned value is the value that was pushed last. If no
  120. * context is available, then the empty string "" is returned.</p>
  121. *
  122. * @return string The innermost diagnostic context.
  123. * @static
  124. */
  125. public static function pop() {
  126. if(count($GLOBALS['log4php.LoggerNDC.ht']) > 0) {
  127. return array_pop($GLOBALS['log4php.LoggerNDC.ht']);
  128. } else {
  129. return '';
  130. }
  131. }
  132. /**
  133. * Looks at the last diagnostic context at the top of this NDC
  134. * without removing it.
  135. *
  136. * <p>The returned value is the value that was pushed last. If no
  137. * context is available, then the empty string "" is returned.</p>
  138. * @return string The innermost diagnostic context.
  139. * @static
  140. */
  141. public static function peek(){
  142. if(count($GLOBALS['log4php.LoggerNDC.ht']) > 0) {
  143. return end($GLOBALS['log4php.LoggerNDC.ht']);
  144. } else {
  145. return '';
  146. }
  147. }
  148. /**
  149. * Push new diagnostic context information for the current thread.
  150. *
  151. * <p>The contents of the <var>message</var> parameter is
  152. * determined solely by the client.
  153. *
  154. * @param string $message The new diagnostic context information.
  155. * @static
  156. */
  157. public static function push($message) {
  158. array_push($GLOBALS['log4php.LoggerNDC.ht'], (string)$message);
  159. }
  160. /**
  161. * Remove the diagnostic context for this thread.
  162. * @static
  163. */
  164. public static function remove() {
  165. LoggerNDC::clear();
  166. }
  167. /**
  168. * Set maximum depth of this diagnostic context. If the current
  169. * depth is smaller or equal to <var>maxDepth</var>, then no
  170. * action is taken.
  171. *
  172. * <p>This method is a convenient alternative to multiple
  173. * {@link pop()} calls. Moreover, it is often the case that at
  174. * the end of complex call sequences, the depth of the NDC is
  175. * unpredictable. The {@link setMaxDepth()} method circumvents
  176. * this problem.
  177. *
  178. * @param integer $maxDepth
  179. * @see getDepth()
  180. * @static
  181. */
  182. public static function setMaxDepth($maxDepth) {
  183. $maxDepth = (int)$maxDepth;
  184. if($maxDepth <= self::HT_SIZE) {
  185. if(LoggerNDC::getDepth() > $maxDepth) {
  186. $GLOBALS['log4php.LoggerNDC.ht'] = array_slice($GLOBALS['log4php.LoggerNDC.ht'], $maxDepth);
  187. }
  188. }
  189. }
  190. }