public LogWatcher(IEnumerable <LogWatcherInfo> logReaderInfos)
 {
     _logWatchers.AddRange(logReaderInfos.Select(x => new LogFileWatcher(x)));
     foreach (var watcher in _logWatchers)
     {
         watcher.OnLogFileFound   += (msg) => OnLogFileFound?.Invoke(msg);
         watcher.OnLogLineIgnored += (msg) => OnLogLineIgnored?.Invoke(msg);
     }
 }
 private void ReadLogFile()
 {
     _running = true;
     FindInitialOffset();
     while (!_stop)
     {
         var fileInfo = new FileInfo(_filePath);
         if (fileInfo.Exists)
         {
             if (!_logFileExists)
             {
                 _logFileExists = true;
                 OnLogFileFound?.Invoke(Info.Name);
             }
             using (var fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
             {
                 fs.Seek(_offset, SeekOrigin.Begin);
                 if (fs.Length == _offset)
                 {
                     Thread.Sleep(LogWatcher.UpdateDelay);
                     continue;
                 }
                 using (var sr = new StreamReader(fs))
                 {
                     string line;
                     while (!sr.EndOfStream && (line = sr.ReadLine()) != null)
                     {
                         if (line.StartsWith("D "))
                         {
                             var next = sr.Peek();
                             if (!sr.EndOfStream && !(next == 'D' || next == 'W' || next == 'E' || next == KoreanMillhouseBugHack))
                             {
                                 break;
                             }
                             var logLine = new LogLine(Info.Name, line);
                             if ((!Info.HasFilters || (Info.StartsWithFilters?.Any(x => logLine.LineContent.StartsWith(x)) ?? false) ||
                                  (Info.ContainsFilters?.Any(x => logLine.LineContent.Contains(x)) ?? false)) &&
                                 logLine.Time >= _startingPoint)
                             {
                                 _lines.Enqueue(logLine);
                             }
                         }
                         else
                         {
                             OnLogLineIgnored?.Invoke($"{Info.Name}: {line}");
                         }
                         _offset += Encoding.UTF8.GetByteCount(line + Environment.NewLine);
                     }
                 }
             }
         }
         Thread.Sleep(LogWatcher.UpdateDelay);
     }
     _running = false;
 }
 public LogFileController(IEnumerable <LogFileMonitorSettings> settings)
 {
     foreach (var setting in settings)
     {
         LogFileMonitor monitor = new LogFileMonitor(setting);
         monitor.OnLogFileFound   += (msg) => OnLogFileFound?.Invoke(msg);
         monitor.OnLogLineIgnored += (msg) => OnLogLineIgnored?.Invoke(msg);
         monitor.OnLogLineError   += (ex) => OnLogLineError?.Invoke(ex);
         _logFileMonitors.Add(monitor);
     }
 }