diff --git a/Logging.Memory/src/Logging.Memory/LogForLevel.cs b/Logging.Memory/src/Logging.Memory/LogForLevel.cs index 9346566..b5214cf 100644 --- a/Logging.Memory/src/Logging.Memory/LogForLevel.cs +++ b/Logging.Memory/src/Logging.Memory/LogForLevel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; namespace Logging.Memory { @@ -10,9 +11,52 @@ internal LogForLevel(int maxLogsCount) logList = new List<(DateTime time, string line)>(maxLogsCount); } - internal int currentLogIndex = 0; + readonly ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim(); + int currentLogIndex = 0; + readonly List<(DateTime time, string line)> logList; - internal List<(DateTime time, string line)> logList; + /// This method is thread-safe + public void Append(DateTime time, string line, int maxLogCount) + { + this.rwLock.EnterWriteLock(); + try + { + if (logList.Count < maxLogCount) + { + logList.Add((time, line)); + } + else + { + logList[currentLogIndex] = (time, line); + } + if (currentLogIndex < maxLogCount - 1) + { + currentLogIndex++; + } + else + { + currentLogIndex = 0; + } + } + finally + { + this.rwLock.ExitWriteLock(); + } + } + + /// This method is thread-safe + public (DateTime time, string line)[] GetEntries() + { + this.rwLock.EnterReadLock(); + try + { + return logList.ToArray(); + } + finally + { + this.rwLock.ExitReadLock(); + } + } } -} +} \ No newline at end of file diff --git a/Logging.Memory/src/Logging.Memory/MemoryLogger.cs b/Logging.Memory/src/Logging.Memory/MemoryLogger.cs index d3d771e..c07966a 100644 --- a/Logging.Memory/src/Logging.Memory/MemoryLogger.cs +++ b/Logging.Memory/src/Logging.Memory/MemoryLogger.cs @@ -10,8 +10,6 @@ /// public class MemoryLogger : ILogger { - private static readonly object lockObj = new object(); - private Func filter; private readonly Func logLineFormatter = null; @@ -59,7 +57,7 @@ public static List LogList get { return logsDictionary - .SelectMany(x => x.Value.logList) + .SelectMany(x => x.Value.GetEntries()) .OrderByDescending(x => x.time) .Take(MaxLogCount) .Reverse() // keep asc sort like in 1st version @@ -76,7 +74,7 @@ public static List LogList { if (logsDictionary.TryGetValue(logLevel, out var log)) { - return log.logList.OrderBy(x => x.time).ToList(); + return log.GetEntries().OrderBy(x => x.time).ToList(); } else { @@ -102,7 +100,7 @@ public static List GetLog(LogLevel logLevel) public static List<(DateTime time,string line)> GetLogGteWithTime(LogLevel minLogLevel) { return logsDictionary.Where(x => x.Key >= minLogLevel) - .SelectMany(x => x.Value.logList) + .SelectMany(x => x.Value.GetEntries()) .OrderBy(x => x.time).ToList(); } @@ -124,7 +122,7 @@ public static List GetLogGte(LogLevel minLogLevel) public static List<(DateTime time, string line)> GetLogLteWithTime(LogLevel maxLogLevel) { return logsDictionary.Where(x => x.Key <= maxLogLevel) - .SelectMany(x => x.Value.logList) + .SelectMany(x => x.Value.GetEntries()) .OrderBy(x => x.time).ToList(); } @@ -184,27 +182,7 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except if (!string.IsNullOrEmpty(message)) { var preparedMessage = this.logLineFormatter(logLevel, Name, message, exception); - lock (lockObj) - { - if (currentLog.logList.Count < MaxLogCount) - { - currentLog.logList.Add((DateTime.Now, preparedMessage)); - } - else - { - currentLog.logList[currentLog.currentLogIndex] = (DateTime.Now, preparedMessage); - } - - if (currentLog.currentLogIndex < MaxLogCount - 1) - { - currentLog.currentLogIndex++; - } - else - { - currentLog.currentLogIndex = 0; - } - } - + currentLog.Append(DateTime.Now, preparedMessage, MaxLogCount); } } }