NDC.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. #region Apache License
  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. #endregion
  19. using System;
  20. using System.Collections;
  21. #if NETCF_1_0
  22. using Stack = log4net.Util.ThreadContextStack.Stack;
  23. #endif
  24. namespace log4net
  25. {
  26. /// <summary>
  27. /// Implementation of Nested Diagnostic Contexts.
  28. /// </summary>
  29. /// <remarks>
  30. /// <note>
  31. /// <para>
  32. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  33. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  34. /// </para>
  35. /// </note>
  36. /// <para>
  37. /// A Nested Diagnostic Context, or NDC in short, is an instrument
  38. /// to distinguish interleaved log output from different sources. Log
  39. /// output is typically interleaved when a server handles multiple
  40. /// clients near-simultaneously.
  41. /// </para>
  42. /// <para>
  43. /// Interleaved log output can still be meaningful if each log entry
  44. /// from different contexts had a distinctive stamp. This is where NDCs
  45. /// come into play.
  46. /// </para>
  47. /// <para>
  48. /// Note that NDCs are managed on a per thread basis. The NDC class
  49. /// is made up of static methods that operate on the context of the
  50. /// calling thread.
  51. /// </para>
  52. /// </remarks>
  53. /// <example>How to push a message into the context
  54. /// <code lang="C#">
  55. /// using(NDC.Push("my context message"))
  56. /// {
  57. /// ... all log calls will have 'my context message' included ...
  58. ///
  59. /// } // at the end of the using block the message is automatically removed
  60. /// </code>
  61. /// </example>
  62. /// <threadsafety static="true" instance="true" />
  63. /// <author>Nicko Cadell</author>
  64. /// <author>Gert Driesen</author>
  65. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  66. public sealed class NDC
  67. {
  68. #region Private Instance Constructors
  69. /// <summary>
  70. /// Initializes a new instance of the <see cref="NDC" /> class.
  71. /// </summary>
  72. /// <remarks>
  73. /// Uses a private access modifier to prevent instantiation of this class.
  74. /// </remarks>
  75. private NDC()
  76. {
  77. }
  78. #endregion Private Instance Constructors
  79. #region Public Static Properties
  80. /// <summary>
  81. /// Gets the current context depth.
  82. /// </summary>
  83. /// <value>The current context depth.</value>
  84. /// <remarks>
  85. /// <note>
  86. /// <para>
  87. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  88. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  89. /// </para>
  90. /// </note>
  91. /// <para>
  92. /// The number of context values pushed onto the context stack.
  93. /// </para>
  94. /// <para>
  95. /// Used to record the current depth of the context. This can then
  96. /// be restored using the <see cref="SetMaxDepth"/> method.
  97. /// </para>
  98. /// </remarks>
  99. /// <seealso cref="SetMaxDepth"/>
  100. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  101. public static int Depth
  102. {
  103. get { return ThreadContext.Stacks["NDC"].Count; }
  104. }
  105. #endregion Public Static Properties
  106. #region Public Static Methods
  107. /// <summary>
  108. /// Clears all the contextual information held on the current thread.
  109. /// </summary>
  110. /// <remarks>
  111. /// <note>
  112. /// <para>
  113. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  114. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  115. /// </para>
  116. /// </note>
  117. /// <para>
  118. /// Clears the stack of NDC data held on the current thread.
  119. /// </para>
  120. /// </remarks>
  121. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  122. public static void Clear()
  123. {
  124. ThreadContext.Stacks["NDC"].Clear();
  125. }
  126. /// <summary>
  127. /// Creates a clone of the stack of context information.
  128. /// </summary>
  129. /// <returns>A clone of the context info for this thread.</returns>
  130. /// <remarks>
  131. /// <note>
  132. /// <para>
  133. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  134. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  135. /// </para>
  136. /// </note>
  137. /// <para>
  138. /// The results of this method can be passed to the <see cref="Inherit"/>
  139. /// method to allow child threads to inherit the context of their
  140. /// parent thread.
  141. /// </para>
  142. /// </remarks>
  143. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  144. public static Stack CloneStack()
  145. {
  146. return ThreadContext.Stacks["NDC"].InternalStack;
  147. }
  148. /// <summary>
  149. /// Inherits the contextual information from another thread.
  150. /// </summary>
  151. /// <param name="stack">The context stack to inherit.</param>
  152. /// <remarks>
  153. /// <note>
  154. /// <para>
  155. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  156. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  157. /// </para>
  158. /// </note>
  159. /// <para>
  160. /// This thread will use the context information from the stack
  161. /// supplied. This can be used to initialize child threads with
  162. /// the same contextual information as their parent threads. These
  163. /// contexts will <b>NOT</b> be shared. Any further contexts that
  164. /// are pushed onto the stack will not be visible to the other.
  165. /// Call <see cref="CloneStack"/> to obtain a stack to pass to
  166. /// this method.
  167. /// </para>
  168. /// </remarks>
  169. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks", true)]*/
  170. public static void Inherit(Stack stack)
  171. {
  172. ThreadContext.Stacks["NDC"].InternalStack = stack;
  173. }
  174. /// <summary>
  175. /// Removes the top context from the stack.
  176. /// </summary>
  177. /// <returns>
  178. /// The message in the context that was removed from the top
  179. /// of the stack.
  180. /// </returns>
  181. /// <remarks>
  182. /// <note>
  183. /// <para>
  184. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  185. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  186. /// </para>
  187. /// </note>
  188. /// <para>
  189. /// Remove the top context from the stack, and return
  190. /// it to the caller. If the stack is empty then an
  191. /// empty string (not <c>null</c>) is returned.
  192. /// </para>
  193. /// </remarks>
  194. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  195. public static string Pop()
  196. {
  197. return ThreadContext.Stacks["NDC"].Pop();
  198. }
  199. /// <summary>
  200. /// Pushes a new context message.
  201. /// </summary>
  202. /// <param name="message">The new context message.</param>
  203. /// <returns>
  204. /// An <see cref="IDisposable"/> that can be used to clean up
  205. /// the context stack.
  206. /// </returns>
  207. /// <remarks>
  208. /// <note>
  209. /// <para>
  210. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  211. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  212. /// </para>
  213. /// </note>
  214. /// <para>
  215. /// Pushes a new context onto the context stack. An <see cref="IDisposable"/>
  216. /// is returned that can be used to clean up the context stack. This
  217. /// can be easily combined with the <c>using</c> keyword to scope the
  218. /// context.
  219. /// </para>
  220. /// </remarks>
  221. /// <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
  222. /// <code lang="C#">
  223. /// using(log4net.NDC.Push("NDC_Message"))
  224. /// {
  225. /// log.Warn("This should have an NDC message");
  226. /// }
  227. /// </code>
  228. /// </example>
  229. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  230. public static IDisposable Push(string message)
  231. {
  232. return ThreadContext.Stacks["NDC"].Push(message);
  233. }
  234. /// <summary>
  235. /// Pushes a new context message.
  236. /// </summary>
  237. /// <param name="messageFormat">The new context message string format.</param>
  238. /// <param name="args">Arguments to be passed into messageFormat.</param>
  239. /// <returns>
  240. /// An <see cref="IDisposable"/> that can be used to clean up
  241. /// the context stack.
  242. /// </returns>
  243. /// <remarks>
  244. /// <note>
  245. /// <para>
  246. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  247. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  248. /// </para>
  249. /// </note>
  250. /// <para>
  251. /// Pushes a new context onto the context stack. An <see cref="IDisposable"/>
  252. /// is returned that can be used to clean up the context stack. This
  253. /// can be easily combined with the <c>using</c> keyword to scope the
  254. /// context.
  255. /// </para>
  256. /// </remarks>
  257. /// <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
  258. /// <code lang="C#">
  259. /// var someValue = "ExampleContext"
  260. /// using(log4net.NDC.PushFormat("NDC_Message {0}", someValue))
  261. /// {
  262. /// log.Warn("This should have an NDC message");
  263. /// }
  264. /// </code>
  265. /// </example>
  266. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  267. public static IDisposable PushFormat(string messageFormat, params object[] args)
  268. {
  269. return Push(string.Format(messageFormat, args));
  270. }
  271. /// <summary>
  272. /// Removes the context information for this thread. It is
  273. /// not required to call this method.
  274. /// </summary>
  275. /// <remarks>
  276. /// <note>
  277. /// <para>
  278. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  279. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  280. /// </para>
  281. /// </note>
  282. /// <para>
  283. /// This method is not implemented.
  284. /// </para>
  285. /// </remarks>
  286. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  287. public static void Remove()
  288. {
  289. }
  290. /// <summary>
  291. /// Forces the stack depth to be at most <paramref name="maxDepth"/>.
  292. /// </summary>
  293. /// <param name="maxDepth">The maximum depth of the stack</param>
  294. /// <remarks>
  295. /// <note>
  296. /// <para>
  297. /// The NDC is deprecated and has been replaced by the <see cref="ThreadContext.Stacks"/>.
  298. /// The current NDC implementation forwards to the <c>ThreadContext.Stacks["NDC"]</c>.
  299. /// </para>
  300. /// </note>
  301. /// <para>
  302. /// Forces the stack depth to be at most <paramref name="maxDepth"/>.
  303. /// This may truncate the head of the stack. This only affects the
  304. /// stack in the current thread. Also it does not prevent it from
  305. /// growing, it only sets the maximum depth at the time of the
  306. /// call. This can be used to return to a known context depth.
  307. /// </para>
  308. /// </remarks>
  309. /*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
  310. public static void SetMaxDepth(int maxDepth)
  311. {
  312. if (maxDepth >= 0)
  313. {
  314. log4net.Util.ThreadContextStack stack = ThreadContext.Stacks["NDC"];
  315. if (maxDepth == 0)
  316. {
  317. stack.Clear();
  318. }
  319. else
  320. {
  321. while(stack.Count > maxDepth)
  322. {
  323. stack.Pop();
  324. }
  325. }
  326. }
  327. }
  328. #endregion Public Static Methods
  329. }
  330. }