using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Wayne.Lib.Log { /// /// Class used to make debug logs. /// /// /// This is an example of how to write a debug log entry. /// /// using (DebugLogger dLog = new DebugLogger(this)) /// { /// if (dLog.IsActive(DebugLogLevel.Detailed)) /// { /// dLog.Add("This is line 1.", DebugLogLevel.Detailed); /// dLog.Add("This is line 2.", "MyCategory", DebugLogLevel.Detailed); /// } /// } /// /// public sealed class DebugLogger : IDisposable, IIdentifiableEntity, IDebugLogger { static NLog.Logger fdcClientLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("FdcClient"); #region Fields private IIdentifiableEntity entity; private bool persistent; private object categoryDebugLevelLock = new object(); private Dictionary categoryDebugLevel = new Dictionary(); private bool logPersistentInfo; private bool disposed; #endregion #region Constructors /// /// Construction of non-persistent DebugLogger. /// /// public DebugLogger(IIdentifiableEntity entity) { if (Logger.IsClosed) disposed = true;// throw new LogException(LogExceptionType.LoggerClosed); if (entity != null) this.entity = entity; else this.entity = IdentifiableEntity.Empty; } /// /// Construction /// /// /// public DebugLogger(IIdentifiableEntity entity, bool persistent) { //if (Logger.IsClosed) // disposed = true;// throw new LogException(LogExceptionType.LoggerClosed); //else //{ // if (entity != null) // this.entity = entity; // else // this.entity = IdentifiableEntity.Empty; // this.persistent = persistent; // if (persistent) // { // Logger.RegisterPersistentLogObject(this as DebugLogger); // logPersistentInfo = true; // } //} } /// /// Finalizer. /// ~DebugLogger() { Dispose(false); } #endregion #region IDisposable Members /// /// Dispose. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Dispose. /// private void Dispose(bool disposing) { if (!disposed) { disposed = true; if (disposing) { if (persistent) { Logger.UnregisterPersistentLogObject(this as DebugLogger); } Logger.UnregisterEntity(entity); } lock (categoryDebugLevelLock) { categoryDebugLevel.Clear(); } } } #endregion #region Properties /// /// The identifiable entity that has created this debug log. /// public IIdentifiableEntity Entity { get { return entity; } } /// /// Tells whether the debug log is persistent or not. /// public bool Persistent { get { return persistent; } } #endregion #region Methods: IsActive /// /// Tells whether the default category is active in the Normal level. /// public bool IsActive() { return true; return !disposed && (DebugLogLevel.Normal <= GetDebugLevel(string.Empty)); } /// /// Tells whether the given category is active in the Normal level. /// public bool IsActive(object category) { return true; return !disposed && (DebugLogLevel.Normal <= GetDebugLevel(category)); } /// /// Tells whether the default category is active in the given level. /// public bool IsActive(DebugLogLevel debugLogLevel) { return true; return !disposed && (debugLogLevel != DebugLogLevel.Excluded) && (debugLogLevel <= GetDebugLevel(string.Empty)); } /// /// Tells whether the given category is active in the given level. /// public bool IsActive(object category, DebugLogLevel debugLogLevel) { return true; return !disposed && (debugLogLevel != DebugLogLevel.Excluded) && (debugLogLevel <= GetDebugLevel(category)); } #endregion #region Methods: GetDebugLevel /// /// Get the current debug level for the default category. /// public DebugLogLevel GetDebugLevel() { return GetDebugLevel(string.Empty); } /// /// Get the current debug level for the given category. /// public DebugLogLevel GetDebugLevel(object category) { return DebugLogLevel.Detailed; if (disposed || Logger.IsClosed) return DebugLogLevel.Excluded; if (category == null) category = string.Empty; // Check if this category's debuglevel is cached. lock (categoryDebugLevelLock) { DebugLogLevel cachedDebugLogLevel; if (categoryDebugLevel.TryGetValue(category, out cachedDebugLogLevel)) return cachedDebugLogLevel; } // Get a list of the logWriters that wants to log me. EntityCategory entityCategory = Logger.DebugConfig.GetEntityCategory(entity, category); LogWriter[] logWriters = Logger.DebugConfig.GetLogWriters(entityCategory); // Iterate through the writers and get the highest debug level. DebugLogLevel debugLogLevel = DebugLogLevel.Excluded; foreach (LogWriter writer in logWriters) { debugLogLevel = MaxDebugLogLevel(debugLogLevel, writer.GetDebugLogLevel(entityCategory)); } // Cache this debug level for future queries. lock (categoryDebugLevelLock) { categoryDebugLevel[category] = debugLogLevel; } return debugLogLevel; } #endregion #region Methods: Add /// /// Adds a new object to the debug log entry. /// /// The log object that are added. [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj")] public void Add(object obj) { fdcClientLogger.Debug(obj); return; if (disposed) return; if (logPersistentInfo) LogPersistentInfo(); Logger.AddEntry(new DebugLogEntry(entity, obj)); } /// /// Adds the object if debuglogger is active with the default category and detaillevel. /// /// /// public void AddIfActive(string formatString, params object[] args) { fdcClientLogger.Debug(string.Format(formatString, args)); return; if (IsActive()) { try { Add(string.Format(formatString, args)); } catch (FormatException fe) { Add(fe); Add(formatString); } } } /// /// Adds the object if debuglogger is active with the default category and detaillevel Detailed . /// /// /// public void AddIfActiveDetailed(string formatString, params object[] args) { fdcClientLogger.Debug(string.Format(formatString, args)); return; if (IsActive(DebugLogLevel.Detailed)) { try { Add(string.Format(formatString, args), DebugLogLevel.Detailed); } catch (FormatException fe) { Add(fe); Add(formatString); } } } /// /// Adds a new object to the debug log entry. /// /// The log object that are added. /// TDB public void Add(object obj, DebugLogLevel level) { fdcClientLogger.Debug(obj); return; if (disposed) return; if (logPersistentInfo) LogPersistentInfo(); Logger.AddEntry(new DebugLogEntry(entity, obj, level)); } /// /// Adds a new object to the debug log entry. /// /// The log object that are added. /// A specific category that this log is about. [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj")] public void Add(object obj, object category) { fdcClientLogger.Debug(obj); return; if (disposed) return; if (logPersistentInfo) LogPersistentInfo(); Logger.AddEntry(new DebugLogEntry(entity, obj, category)); } /// /// Adds a new object to the debug log entry. /// /// The log object that are added. /// A specific category that this log is about. /// TDB [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "obj")] public void Add(object obj, object category, DebugLogLevel level) { fdcClientLogger.Debug(obj); return; if (disposed) return; if (logPersistentInfo) LogPersistentInfo(); Logger.AddEntry(new DebugLogEntry(entity, obj, category, level)); } /// /// /// private void LogPersistentInfo() { //Logger.AddEntry(new DebugLogEntry(entity, "Hooked persistent DebugLogger to logfile: " + IdentifiableEntity.ToString(entity, true), string.Empty, DebugLogLevel.Normal)); //logPersistentInfo = false; } #endregion #region Internal Methods /// /// Invalidates the internal flags for configuration reading. /// internal void Invalidate() { //lock (categoryDebugLevelLock) //{ // categoryDebugLevel.Clear(); //} } /// /// Static method to get the highest of two DebugLogLevel's. /// /// /// /// public static DebugLogLevel MaxDebugLogLevel(DebugLogLevel level1, DebugLogLevel level2) { if (level1 > level2) return level1; else return level2; } #endregion #region IIdentifiableEntity Members /// /// The Id of the Entity. /// public int Id { get { return entity.Id; } } /// /// The EntityType of the Entity. /// public string EntityType { get { return entity.EntityType; } } /// /// This is used by the logger and should never be set by implementing classes /// public string FullEntityName { get; set; } /// /// The EntitySubType of the Entity. /// public string EntitySubType { get { return entity.EntitySubType; } } /// /// The ParentEntity of the Entity. /// public IIdentifiableEntity ParentEntity { get { return entity.ParentEntity; } } #endregion } }