using System; using System.Collections.Generic; using System.Text; using ServiceStack.Logging; namespace ServiceStack.Common.Support { /// /// Note: InMemoryLog keeps all logs in memory, so don't use it long running exceptions /// /// Returns a thread-safe InMemoryLog which you can use while *TESTING* /// to provide a detailed analysis of your logs. /// public class InMemoryLogFactory : ILogFactory { public ILog GetLogger(Type type) { return new InMemoryLog(type.Name); } public ILog GetLogger(string typeName) { return new InMemoryLog(typeName); } } public class InMemoryLog : ILog { private readonly object syncLock = new object(); public string LoggerName { get; private set; } public StringBuilder CombinedLog { get; private set; } public List DebugEntries { get; set; } public List DebugExceptions { get; set; } public List InfoEntries { get; set; } public List InfoExceptions { get; set; } public List WarnEntries { get; set; } public List WarnExceptions { get; set; } public List ErrorEntries { get; set; } public List ErrorExceptions { get; set; } public List FatalEntries { get; set; } public List FatalExceptions { get; set; } public InMemoryLog(string loggerName) { this.LoggerName = loggerName; this.CombinedLog = new StringBuilder(); this.DebugEntries = new List(); this.DebugExceptions = new List(); this.InfoEntries = new List(); this.InfoExceptions = new List(); this.WarnEntries = new List(); this.WarnExceptions = new List(); this.ErrorEntries = new List(); this.ErrorExceptions = new List(); this.FatalEntries = new List(); this.FatalExceptions = new List(); } public bool HasExceptions { get { return this.DebugExceptions.Count > 0 || this.InfoExceptions.Count > 0 || this.WarnExceptions.Count > 0 || this.ErrorExceptions.Count > 0 || this.FatalExceptions.Count > 0; } } private void AppendToLog(ICollection logEntries, string format, params object[] args) { if (format == null) return; AppendToLog(logEntries, string.Format(format, args)); } private void AppendToLog(ICollection logEntries, object message) { if (message == null) return; AppendToLog(logEntries, message.ToString()); } private void AppendToLog( ICollection logEntries, ICollection logExceptions, object message, Exception ex) { if (ex != null) { lock (syncLock) { logExceptions.Add(ex); } } if (message == null) return; AppendToLog(logEntries, message.ToString()); } private void AppendToLog(ICollection logEntries, string message) { lock (this) { logEntries.Add(message); CombinedLog.AppendLine(message); } } public void Debug(object message) { AppendToLog(DebugEntries, message); } public void Debug(object message, Exception exception) { AppendToLog(DebugEntries, DebugExceptions, message, exception); } public void DebugFormat(string format, params object[] args) { AppendToLog(DebugEntries, format, args); } public void Error(object message) { AppendToLog(ErrorEntries, message); } public void Error(object message, Exception exception) { AppendToLog(ErrorEntries, ErrorExceptions, message, exception); } public void ErrorFormat(string format, params object[] args) { AppendToLog(ErrorEntries, format, args); } public void Fatal(object message) { AppendToLog(FatalEntries, message); } public void Fatal(object message, Exception exception) { AppendToLog(FatalEntries, FatalExceptions, message, exception); } public void FatalFormat(string format, params object[] args) { AppendToLog(FatalEntries, format, args); } public void Info(object message) { AppendToLog(InfoEntries, message); } public void Info(object message, Exception exception) { AppendToLog(InfoEntries, InfoExceptions, message, exception); } public void InfoFormat(string format, params object[] args) { AppendToLog(InfoEntries, format, args); } public void Warn(object message) { AppendToLog(WarnEntries, message); } public void Warn(object message, Exception exception) { AppendToLog(WarnEntries, WarnExceptions, message, exception); } public void WarnFormat(string format, params object[] args) { AppendToLog(WarnEntries, format, args); } public bool IsDebugEnabled { get { return true; } } } }