OnlyOnceErrorHandler.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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 log4net.Core;
  21. namespace log4net.Util
  22. {
  23. /// <summary>
  24. /// Implements log4net's default error handling policy which consists
  25. /// of emitting a message for the first error in an appender and
  26. /// ignoring all subsequent errors.
  27. /// </summary>
  28. /// <remarks>
  29. /// <para>
  30. /// The error message is processed using the LogLog sub-system by default.
  31. /// </para>
  32. /// <para>
  33. /// This policy aims at protecting an otherwise working application
  34. /// from being flooded with error messages when logging fails.
  35. /// </para>
  36. /// </remarks>
  37. /// <author>Nicko Cadell</author>
  38. /// <author>Gert Driesen</author>
  39. /// <author>Ron Grabowski</author>
  40. public class OnlyOnceErrorHandler : IErrorHandler
  41. {
  42. #region Public Instance Constructors
  43. /// <summary>
  44. /// Default Constructor
  45. /// </summary>
  46. /// <remarks>
  47. /// <para>
  48. /// Initializes a new instance of the <see cref="OnlyOnceErrorHandler" /> class.
  49. /// </para>
  50. /// </remarks>
  51. public OnlyOnceErrorHandler()
  52. {
  53. m_prefix = "";
  54. }
  55. /// <summary>
  56. /// Constructor
  57. /// </summary>
  58. /// <param name="prefix">The prefix to use for each message.</param>
  59. /// <remarks>
  60. /// <para>
  61. /// Initializes a new instance of the <see cref="OnlyOnceErrorHandler" /> class
  62. /// with the specified prefix.
  63. /// </para>
  64. /// </remarks>
  65. public OnlyOnceErrorHandler(string prefix)
  66. {
  67. m_prefix = prefix;
  68. }
  69. #endregion Public Instance Constructors
  70. #region Public Instance Methods
  71. /// <summary>
  72. /// Reset the error handler back to its initial disabled state.
  73. /// </summary>
  74. public void Reset()
  75. {
  76. m_enabledDateUtc = DateTime.MinValue;
  77. m_errorCode = ErrorCode.GenericFailure;
  78. m_exception = null;
  79. m_message = null;
  80. m_firstTime = true;
  81. }
  82. #region Implementation of IErrorHandler
  83. /// <summary>
  84. /// Log an Error
  85. /// </summary>
  86. /// <param name="message">The error message.</param>
  87. /// <param name="e">The exception.</param>
  88. /// <param name="errorCode">The internal error code.</param>
  89. /// <remarks>
  90. /// <para>
  91. /// Invokes <see cref="FirstError"/> if and only if this is the first error or the first error after <see cref="Reset"/> has been called.
  92. /// </para>
  93. /// </remarks>
  94. public void Error(string message, Exception e, ErrorCode errorCode)
  95. {
  96. if (m_firstTime)
  97. {
  98. FirstError(message, e, errorCode);
  99. }
  100. }
  101. /// <summary>
  102. /// Log the very first error
  103. /// </summary>
  104. /// <param name="message">The error message.</param>
  105. /// <param name="e">The exception.</param>
  106. /// <param name="errorCode">The internal error code.</param>
  107. /// <remarks>
  108. /// <para>
  109. /// Sends the error information to <see cref="LogLog"/>'s Error method.
  110. /// </para>
  111. /// </remarks>
  112. public virtual void FirstError(string message, Exception e, ErrorCode errorCode) {
  113. m_enabledDateUtc = DateTime.UtcNow;
  114. m_errorCode = errorCode;
  115. m_exception = e;
  116. m_message = message;
  117. m_firstTime = false;
  118. if (LogLog.InternalDebugging && !LogLog.QuietMode) {
  119. LogLog.Error(declaringType, "[" + m_prefix + "] ErrorCode: " + errorCode.ToString() + ". " + message, e);
  120. }
  121. }
  122. /// <summary>
  123. /// Log an Error
  124. /// </summary>
  125. /// <param name="message">The error message.</param>
  126. /// <param name="e">The exception.</param>
  127. /// <remarks>
  128. /// <para>
  129. /// Invokes <see cref="FirstError"/> if and only if this is the first error or the first error after <see cref="Reset"/> has been called.
  130. /// </para>
  131. /// </remarks>
  132. public void Error(string message, Exception e)
  133. {
  134. Error(message, e, ErrorCode.GenericFailure);
  135. }
  136. /// <summary>
  137. /// Log an error
  138. /// </summary>
  139. /// <param name="message">The error message.</param>
  140. /// <remarks>
  141. /// <para>
  142. /// Invokes <see cref="FirstError"/> if and only if this is the first error or the first error after <see cref="Reset"/> has been called.
  143. /// </para>
  144. /// </remarks>
  145. public void Error(string message)
  146. {
  147. Error(message, null, ErrorCode.GenericFailure);
  148. }
  149. #endregion Implementation of IErrorHandler
  150. #endregion
  151. #region Public Instance Properties
  152. /// <summary>
  153. /// Is error logging enabled
  154. /// </summary>
  155. /// <remarks>
  156. /// <para>
  157. /// Is error logging enabled. Logging is only enabled for the
  158. /// first error delivered to the <see cref="OnlyOnceErrorHandler"/>.
  159. /// </para>
  160. /// </remarks>
  161. public bool IsEnabled
  162. {
  163. get { return m_firstTime; }
  164. }
  165. /// <summary>
  166. /// The date the first error that trigged this error handler occurred, or <see cref="DateTime.MinValue"/> if it has not been triggered.
  167. /// </summary>
  168. public DateTime EnabledDate
  169. {
  170. get
  171. {
  172. if (m_enabledDateUtc == DateTime.MinValue) return DateTime.MinValue;
  173. return m_enabledDateUtc.ToLocalTime();
  174. }
  175. }
  176. /// <summary>
  177. /// The UTC date the first error that trigged this error handler occured, or <see cref="DateTime.MinValue"/> if it has not been triggered.
  178. /// </summary>
  179. public DateTime EnabledDateUtc
  180. {
  181. get { return m_enabledDateUtc; }
  182. }
  183. /// <summary>
  184. /// The message from the first error that trigged this error handler.
  185. /// </summary>
  186. public string ErrorMessage
  187. {
  188. get { return m_message; }
  189. }
  190. /// <summary>
  191. /// The exception from the first error that trigged this error handler.
  192. /// </summary>
  193. /// <remarks>
  194. /// May be <see langword="null" />.
  195. /// </remarks>
  196. public Exception Exception
  197. {
  198. get { return m_exception; }
  199. }
  200. /// <summary>
  201. /// The error code from the first error that trigged this error handler.
  202. /// </summary>
  203. /// <remarks>
  204. /// Defaults to <see cref="log4net.Core.ErrorCode.GenericFailure"/>
  205. /// </remarks>
  206. public ErrorCode ErrorCode
  207. {
  208. get { return m_errorCode; }
  209. }
  210. #endregion
  211. #region Private Instance Fields
  212. /// <summary>
  213. /// The UTC date the error was recorded.
  214. /// </summary>
  215. private DateTime m_enabledDateUtc;
  216. /// <summary>
  217. /// Flag to indicate if it is the first error
  218. /// </summary>
  219. private bool m_firstTime = true;
  220. /// <summary>
  221. /// The message recorded during the first error.
  222. /// </summary>
  223. private string m_message = null;
  224. /// <summary>
  225. /// The exception recorded during the first error.
  226. /// </summary>
  227. private Exception m_exception = null;
  228. /// <summary>
  229. /// The error code recorded during the first error.
  230. /// </summary>
  231. private ErrorCode m_errorCode = ErrorCode.GenericFailure;
  232. /// <summary>
  233. /// String to prefix each message with
  234. /// </summary>
  235. private readonly string m_prefix;
  236. #endregion Private Instance Fields
  237. #region Private Static Fields
  238. /// <summary>
  239. /// The fully qualified type of the OnlyOnceErrorHandler class.
  240. /// </summary>
  241. /// <remarks>
  242. /// Used by the internal logger to record the Type of the
  243. /// log message.
  244. /// </remarks>
  245. private readonly static Type declaringType = typeof(OnlyOnceErrorHandler);
  246. #endregion
  247. }
  248. }