TraceAppender.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. #define TRACE
  20. using log4net.Layout;
  21. using log4net.Core;
  22. namespace log4net.Appender
  23. {
  24. /// <summary>
  25. /// Appends log events to the <see cref="System.Diagnostics.Trace"/> system.
  26. /// </summary>
  27. /// <remarks>
  28. /// <para>
  29. /// The application configuration file can be used to control what listeners
  30. /// are actually used. See the MSDN documentation for the
  31. /// <see cref="System.Diagnostics.Trace"/> class for details on configuring the
  32. /// trace system.
  33. /// </para>
  34. /// <para>
  35. /// Events are written using the <c>System.Diagnostics.Trace.Write(string,string)</c>
  36. /// method. The event's logger name is the default value for the category parameter
  37. /// of the Write method.
  38. /// </para>
  39. /// <para>
  40. /// <b>Compact Framework</b><br />
  41. /// The Compact Framework does not support the <see cref="System.Diagnostics.Trace"/>
  42. /// class for any operation except <c>Assert</c>. When using the Compact Framework this
  43. /// appender will write to the <see cref="System.Diagnostics.Debug"/> system rather than
  44. /// the Trace system. This appender will therefore behave like the <see cref="DebugAppender"/>.
  45. /// </para>
  46. /// </remarks>
  47. /// <author>Douglas de la Torre</author>
  48. /// <author>Nicko Cadell</author>
  49. /// <author>Gert Driesen</author>
  50. /// <author>Ron Grabowski</author>
  51. public class TraceAppender : AppenderSkeleton
  52. {
  53. #region Public Instance Constructors
  54. /// <summary>
  55. /// Initializes a new instance of the <see cref="TraceAppender" />.
  56. /// </summary>
  57. /// <remarks>
  58. /// <para>
  59. /// Default constructor.
  60. /// </para>
  61. /// </remarks>
  62. public TraceAppender()
  63. {
  64. }
  65. /// <summary>
  66. /// Initializes a new instance of the <see cref="TraceAppender" />
  67. /// with a specified layout.
  68. /// </summary>
  69. /// <param name="layout">The layout to use with this appender.</param>
  70. /// <remarks>
  71. /// <para>
  72. /// Obsolete constructor.
  73. /// </para>
  74. /// </remarks>
  75. [System.Obsolete("Instead use the default constructor and set the Layout property")]
  76. public TraceAppender(ILayout layout)
  77. {
  78. Layout = layout;
  79. }
  80. #endregion Public Instance Constructors
  81. #region Public Instance Properties
  82. /// <summary>
  83. /// Gets or sets a value that indicates whether the appender will
  84. /// flush at the end of each write.
  85. /// </summary>
  86. /// <remarks>
  87. /// <para>The default behavior is to flush at the end of each
  88. /// write. If the option is set to<c>false</c>, then the underlying
  89. /// stream can defer writing to physical medium to a later time.
  90. /// </para>
  91. /// <para>
  92. /// Avoiding the flush operation at the end of each append results
  93. /// in a performance gain of 10 to 20 percent. However, there is safety
  94. /// trade-off involved in skipping flushing. Indeed, when flushing is
  95. /// skipped, then it is likely that the last few log events will not
  96. /// be recorded on disk when the application exits. This is a high
  97. /// price to pay even for a 20% performance gain.
  98. /// </para>
  99. /// </remarks>
  100. public bool ImmediateFlush
  101. {
  102. get { return m_immediateFlush; }
  103. set { m_immediateFlush = value; }
  104. }
  105. /// <summary>
  106. /// The category parameter sent to the Trace method.
  107. /// </summary>
  108. /// <remarks>
  109. /// <para>
  110. /// Defaults to %logger which will use the logger name of the current
  111. /// <see cref="LoggingEvent"/> as the category parameter.
  112. /// </para>
  113. /// <para>
  114. /// </para>
  115. /// </remarks>
  116. public PatternLayout Category
  117. {
  118. get { return m_category; }
  119. set { m_category = value; }
  120. }
  121. #endregion Public Instance Properties
  122. #region Override implementation of AppenderSkeleton
  123. /// <summary>
  124. /// Writes the logging event to the <see cref="System.Diagnostics.Trace"/> system.
  125. /// </summary>
  126. /// <param name="loggingEvent">The event to log.</param>
  127. /// <remarks>
  128. /// <para>
  129. /// Writes the logging event to the <see cref="System.Diagnostics.Trace"/> system.
  130. /// </para>
  131. /// </remarks>
  132. override protected void Append(LoggingEvent loggingEvent)
  133. {
  134. //
  135. // Write the string to the Trace system
  136. //
  137. #if NETCF
  138. System.Diagnostics.Debug.Write(RenderLoggingEvent(loggingEvent), m_category.Format(loggingEvent));
  139. #else
  140. System.Diagnostics.Trace.Write(RenderLoggingEvent(loggingEvent), m_category.Format(loggingEvent));
  141. #endif
  142. //
  143. // Flush the Trace system if needed
  144. //
  145. if (m_immediateFlush)
  146. {
  147. #if NETCF
  148. System.Diagnostics.Debug.Flush();
  149. #else
  150. System.Diagnostics.Trace.Flush();
  151. #endif
  152. }
  153. }
  154. /// <summary>
  155. /// This appender requires a <see cref="Layout"/> to be set.
  156. /// </summary>
  157. /// <value><c>true</c></value>
  158. /// <remarks>
  159. /// <para>
  160. /// This appender requires a <see cref="Layout"/> to be set.
  161. /// </para>
  162. /// </remarks>
  163. override protected bool RequiresLayout
  164. {
  165. get { return true; }
  166. }
  167. #endregion Override implementation of AppenderSkeleton
  168. #region Private Instance Fields
  169. /// <summary>
  170. /// Immediate flush means that the underlying writer or output stream
  171. /// will be flushed at the end of each append operation.
  172. /// </summary>
  173. /// <remarks>
  174. /// <para>
  175. /// Immediate flush is slower but ensures that each append request is
  176. /// actually written. If <see cref="ImmediateFlush"/> is set to
  177. /// <c>false</c>, then there is a good chance that the last few
  178. /// logs events are not actually written to persistent media if and
  179. /// when the application crashes.
  180. /// </para>
  181. /// <para>
  182. /// The default value is <c>true</c>.</para>
  183. /// </remarks>
  184. private bool m_immediateFlush = true;
  185. /// <summary>
  186. /// Defaults to %logger
  187. /// </summary>
  188. private PatternLayout m_category = new PatternLayout("%logger");
  189. #endregion Private Instance Fields
  190. /// <summary>
  191. /// Flushes any buffered log data.
  192. /// </summary>
  193. /// <param name="millisecondsTimeout">The maximum time to wait for logging events to be flushed.</param>
  194. /// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
  195. public override bool Flush(int millisecondsTimeout)
  196. {
  197. // Nothing to do if ImmediateFlush is true
  198. if (m_immediateFlush) return true;
  199. // System.Diagnostics.Trace and System.Diagnostics.Debug are thread-safe, so no need for lock(this).
  200. #if NETCF
  201. System.Diagnostics.Debug.Flush();
  202. #else
  203. System.Diagnostics.Trace.Flush();
  204. #endif
  205. return true;
  206. }
  207. }
  208. }