DebugLogger.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics.CodeAnalysis;
  4. namespace Wayne.Lib.Log
  5. {
  6. /// <summary>
  7. /// Class used to make debug logs.
  8. /// </summary>
  9. /// <example>
  10. /// This is an example of how to write a debug log entry.
  11. /// <code>
  12. /// using (DebugLogger dLog = new DebugLogger(this))
  13. /// {
  14. /// if (dLog.IsActive(DebugLogLevel.Detailed))
  15. /// {
  16. /// dLog.Add("This is line 1.", DebugLogLevel.Detailed);
  17. /// dLog.Add("This is line 2.", "MyCategory", DebugLogLevel.Detailed);
  18. /// }
  19. /// }
  20. /// </code>
  21. /// </example>
  22. public sealed class DebugLogger : IDisposable, IIdentifiableEntity, IDebugLogger
  23. {
  24. static NLog.Logger fdcClientLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("FdcClient");
  25. #region Fields
  26. private IIdentifiableEntity entity;
  27. private bool persistent;
  28. private object categoryDebugLevelLock = new object();
  29. private Dictionary<object, DebugLogLevel> categoryDebugLevel = new Dictionary<object, DebugLogLevel>();
  30. private bool logPersistentInfo;
  31. private bool disposed;
  32. #endregion
  33. #region Constructors
  34. /// <summary>
  35. /// Construction of non-persistent DebugLogger.
  36. /// </summary>
  37. /// <param name="entity"></param>
  38. public DebugLogger(IIdentifiableEntity entity)
  39. {
  40. if (Logger.IsClosed)
  41. disposed = true;// throw new LogException(LogExceptionType.LoggerClosed);
  42. if (entity != null)
  43. this.entity = entity;
  44. else
  45. this.entity = IdentifiableEntity.Empty;
  46. }
  47. /// <summary>
  48. /// Construction
  49. /// </summary>
  50. /// <param name="entity"></param>
  51. /// <param name="persistent"></param>
  52. public DebugLogger(IIdentifiableEntity entity, bool persistent)
  53. {
  54. //if (Logger.IsClosed)
  55. // disposed = true;// throw new LogException(LogExceptionType.LoggerClosed);
  56. //else
  57. //{
  58. // if (entity != null)
  59. // this.entity = entity;
  60. // else
  61. // this.entity = IdentifiableEntity.Empty;
  62. // this.persistent = persistent;
  63. // if (persistent)
  64. // {
  65. // Logger.RegisterPersistentLogObject(this as DebugLogger);
  66. // logPersistentInfo = true;
  67. // }
  68. //}
  69. }
  70. /// <summary>
  71. /// Finalizer.
  72. /// </summary>
  73. ~DebugLogger()
  74. {
  75. Dispose(false);
  76. }
  77. #endregion
  78. #region IDisposable Members
  79. /// <summary>
  80. /// Dispose.
  81. /// </summary>
  82. public void Dispose()
  83. {
  84. Dispose(true);
  85. GC.SuppressFinalize(this);
  86. }
  87. /// <summary>
  88. /// Dispose.
  89. /// </summary>
  90. private void Dispose(bool disposing)
  91. {
  92. if (!disposed)
  93. {
  94. disposed = true;
  95. if (disposing)
  96. {
  97. if (persistent)
  98. {
  99. Logger.UnregisterPersistentLogObject(this as DebugLogger);
  100. }
  101. Logger.UnregisterEntity(entity);
  102. }
  103. lock (categoryDebugLevelLock)
  104. {
  105. categoryDebugLevel.Clear();
  106. }
  107. }
  108. }
  109. #endregion
  110. #region Properties
  111. /// <summary>
  112. /// The identifiable entity that has created this debug log.
  113. /// </summary>
  114. public IIdentifiableEntity Entity
  115. {
  116. get { return entity; }
  117. }
  118. /// <summary>
  119. /// Tells whether the debug log is persistent or not.
  120. /// </summary>
  121. public bool Persistent
  122. {
  123. get { return persistent; }
  124. }
  125. #endregion
  126. #region Methods: IsActive
  127. /// <summary>
  128. /// Tells whether the default category is active in the Normal level.
  129. /// </summary>
  130. public bool IsActive()
  131. {
  132. return true;
  133. return !disposed && (DebugLogLevel.Normal <= GetDebugLevel(string.Empty));
  134. }
  135. /// <summary>
  136. /// Tells whether the given category is active in the Normal level.
  137. /// </summary>
  138. public bool IsActive(object category)
  139. {
  140. return true;
  141. return !disposed && (DebugLogLevel.Normal <= GetDebugLevel(category));
  142. }
  143. /// <summary>
  144. /// Tells whether the default category is active in the given level.
  145. /// </summary>
  146. public bool IsActive(DebugLogLevel debugLogLevel)
  147. {
  148. return true;
  149. return !disposed && (debugLogLevel != DebugLogLevel.Excluded) && (debugLogLevel <= GetDebugLevel(string.Empty));
  150. }
  151. /// <summary>
  152. /// Tells whether the given category is active in the given level.
  153. /// </summary>
  154. public bool IsActive(object category, DebugLogLevel debugLogLevel)
  155. {
  156. return true;
  157. return !disposed && (debugLogLevel != DebugLogLevel.Excluded) && (debugLogLevel <= GetDebugLevel(category));
  158. }
  159. #endregion
  160. #region Methods: GetDebugLevel
  161. /// <summary>
  162. /// Get the current debug level for the default category.
  163. /// </summary>
  164. public DebugLogLevel GetDebugLevel()
  165. {
  166. return GetDebugLevel(string.Empty);
  167. }
  168. /// <summary>
  169. /// Get the current debug level for the given category.
  170. /// </summary>
  171. public DebugLogLevel GetDebugLevel(object category)
  172. {
  173. return DebugLogLevel.Detailed;
  174. if (disposed || Logger.IsClosed)
  175. return DebugLogLevel.Excluded;
  176. if (category == null)
  177. category = string.Empty;
  178. // Check if this category's debuglevel is cached.
  179. lock (categoryDebugLevelLock)
  180. {
  181. DebugLogLevel cachedDebugLogLevel;
  182. if (categoryDebugLevel.TryGetValue(category, out cachedDebugLogLevel))
  183. return cachedDebugLogLevel;
  184. }
  185. // Get a list of the logWriters that wants to log me.
  186. EntityCategory entityCategory = Logger.DebugConfig.GetEntityCategory(entity, category);
  187. LogWriter[] logWriters = Logger.DebugConfig.GetLogWriters(entityCategory);
  188. // Iterate through the writers and get the highest debug level.
  189. DebugLogLevel debugLogLevel = DebugLogLevel.Excluded;
  190. foreach (LogWriter writer in logWriters)
  191. {
  192. debugLogLevel = MaxDebugLogLevel(debugLogLevel, writer.GetDebugLogLevel(entityCategory));
  193. }
  194. // Cache this debug level for future queries.
  195. lock (categoryDebugLevelLock)
  196. {
  197. categoryDebugLevel[category] = debugLogLevel;
  198. }
  199. return debugLogLevel;
  200. }
  201. #endregion
  202. #region Methods: Add
  203. /// <summary>
  204. /// Adds a new object to the debug log entry.
  205. /// </summary>
  206. /// <param name="obj">The log object that are added.</param>
  207. [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj")]
  208. public void Add(object obj)
  209. {
  210. fdcClientLogger.Debug(obj);
  211. return;
  212. if (disposed)
  213. return;
  214. if (logPersistentInfo)
  215. LogPersistentInfo();
  216. Logger.AddEntry(new DebugLogEntry(entity, obj));
  217. }
  218. /// <summary>
  219. /// Adds the object if debuglogger is active with the default category and detaillevel.
  220. /// </summary>
  221. /// <param name="args"></param>
  222. /// <param name="formatString"></param>
  223. public void AddIfActive(string formatString, params object[] args)
  224. {
  225. fdcClientLogger.Debug(string.Format(formatString, args));
  226. return;
  227. if (IsActive())
  228. {
  229. try
  230. {
  231. Add(string.Format(formatString, args));
  232. }
  233. catch (FormatException fe)
  234. {
  235. Add(fe);
  236. Add(formatString);
  237. }
  238. }
  239. }
  240. /// <summary>
  241. /// Adds the object if debuglogger is active with the default category and detaillevel Detailed .
  242. /// </summary>
  243. /// <param name="formatString"></param>
  244. /// <param name="args"></param>
  245. public void AddIfActiveDetailed(string formatString, params object[] args)
  246. {
  247. fdcClientLogger.Debug(string.Format(formatString, args));
  248. return;
  249. if (IsActive(DebugLogLevel.Detailed))
  250. {
  251. try
  252. {
  253. Add(string.Format(formatString, args), DebugLogLevel.Detailed);
  254. }
  255. catch (FormatException fe)
  256. {
  257. Add(fe);
  258. Add(formatString);
  259. }
  260. }
  261. }
  262. /// <summary>
  263. /// Adds a new object to the debug log entry.
  264. /// </summary>
  265. /// <param name="obj">The log object that are added.</param>
  266. /// <param name="level">TDB</param>
  267. public void Add(object obj, DebugLogLevel level)
  268. {
  269. fdcClientLogger.Debug(obj);
  270. return;
  271. if (disposed)
  272. return;
  273. if (logPersistentInfo)
  274. LogPersistentInfo();
  275. Logger.AddEntry(new DebugLogEntry(entity, obj, level));
  276. }
  277. /// <summary>
  278. /// Adds a new object to the debug log entry.
  279. /// </summary>
  280. /// <param name="obj">The log object that are added.</param>
  281. /// <param name="category">A specific category that this log is about.</param>
  282. [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj")]
  283. public void Add(object obj, object category)
  284. {
  285. fdcClientLogger.Debug(obj);
  286. return;
  287. if (disposed)
  288. return;
  289. if (logPersistentInfo)
  290. LogPersistentInfo();
  291. Logger.AddEntry(new DebugLogEntry(entity, obj, category));
  292. }
  293. /// <summary>
  294. /// Adds a new object to the debug log entry.
  295. /// </summary>
  296. /// <param name="obj">The log object that are added.</param>
  297. /// <param name="category">A specific category that this log is about.</param>
  298. /// <param name="level">TDB</param>
  299. [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj")]
  300. public void Add(object obj, object category, DebugLogLevel level)
  301. {
  302. fdcClientLogger.Debug(obj);
  303. return;
  304. if (disposed)
  305. return;
  306. if (logPersistentInfo)
  307. LogPersistentInfo();
  308. Logger.AddEntry(new DebugLogEntry(entity, obj, category, level));
  309. }
  310. /// <summary>
  311. ///
  312. /// </summary>
  313. private void LogPersistentInfo()
  314. {
  315. //Logger.AddEntry(new DebugLogEntry(entity, "Hooked persistent DebugLogger to logfile: " + IdentifiableEntity.ToString(entity, true), string.Empty, DebugLogLevel.Normal));
  316. //logPersistentInfo = false;
  317. }
  318. #endregion
  319. #region Internal Methods
  320. /// <summary>
  321. /// Invalidates the internal flags for configuration reading.
  322. /// </summary>
  323. internal void Invalidate()
  324. {
  325. //lock (categoryDebugLevelLock)
  326. //{
  327. // categoryDebugLevel.Clear();
  328. //}
  329. }
  330. /// <summary>
  331. /// Static method to get the highest of two DebugLogLevel's.
  332. /// </summary>
  333. /// <param name="level1"></param>
  334. /// <param name="level2"></param>
  335. /// <returns></returns>
  336. public static DebugLogLevel MaxDebugLogLevel(DebugLogLevel level1, DebugLogLevel level2)
  337. {
  338. if (level1 > level2)
  339. return level1;
  340. else
  341. return level2;
  342. }
  343. #endregion
  344. #region IIdentifiableEntity Members
  345. /// <summary>
  346. /// The Id of the Entity.
  347. /// </summary>
  348. public int Id
  349. {
  350. get { return entity.Id; }
  351. }
  352. /// <summary>
  353. /// The EntityType of the Entity.
  354. /// </summary>
  355. public string EntityType
  356. {
  357. get { return entity.EntityType; }
  358. }
  359. /// <summary>
  360. /// This is used by the logger and should never be set by implementing classes
  361. /// </summary>
  362. public string FullEntityName { get; set; }
  363. /// <summary>
  364. /// The EntitySubType of the Entity.
  365. /// </summary>
  366. public string EntitySubType
  367. {
  368. get { return entity.EntitySubType; }
  369. }
  370. /// <summary>
  371. /// The ParentEntity of the Entity.
  372. /// </summary>
  373. public IIdentifiableEntity ParentEntity
  374. {
  375. get { return entity.ParentEntity; }
  376. }
  377. #endregion
  378. }
  379. }