DebugAppender.cs 7.2 KB

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