2
2
using LogExpert . Entities ;
3
3
using LogExpert . Entities . EventArgs ;
4
4
using LogExpert . Interface ;
5
-
6
5
using NLog ;
7
-
8
6
using System ;
9
7
using System . Collections . Generic ;
10
8
using System . IO ;
@@ -22,7 +20,17 @@ public class LogfileReader : IAutoLogLineColumnizerCallback
22
20
23
21
private readonly GetLogLineFx _logLineFx ;
24
22
25
- private readonly string _fileName ;
23
+ private string FileName
24
+ {
25
+ get ; init
26
+ {
27
+ var uri = new Uri ( value ) ;
28
+ if ( uri . IsFile )
29
+ {
30
+ field = uri . LocalPath ; // Convert the URI to a local file path
31
+ }
32
+ }
33
+ }
26
34
private readonly int _MAX_BUFFERS = 10 ;
27
35
private readonly int _MAX_LINES_PER_BUFFER = 100 ;
28
36
@@ -39,7 +47,6 @@ public class LogfileReader : IAutoLogLineColumnizerCallback
39
47
private long _fileLength ;
40
48
41
49
private Task _garbageCollectorTask ;
42
- private Task _monitorTask ;
43
50
private readonly CancellationTokenSource cts = new ( ) ;
44
51
45
52
private bool _isDeleted ;
@@ -51,7 +58,7 @@ public class LogfileReader : IAutoLogLineColumnizerCallback
51
58
52
59
private ReaderWriterLock _lruCacheDictLock ;
53
60
54
-
61
+ private FileSystemWatcher _watcher ;
55
62
private bool _shouldStop ;
56
63
private ILogFileInfo _watchedILogFileInfo ;
57
64
@@ -66,7 +73,7 @@ public LogfileReader(string fileName, EncodingOptions encodingOptions, bool mult
66
73
return ;
67
74
}
68
75
69
- _fileName = fileName ;
76
+ FileName = fileName ;
70
77
EncodingOptions = encodingOptions ;
71
78
IsMultiFile = multiFile ;
72
79
_MAX_BUFFERS = bufferCount ;
@@ -120,7 +127,7 @@ public LogfileReader(string[] fileNames, EncodingOptions encodingOptions, int bu
120
127
}
121
128
122
129
_watchedILogFileInfo = fileInfo ;
123
- _fileName = fileInfo . FullName ;
130
+ FileName = fileInfo . FullName ;
124
131
125
132
StartGCThread ( ) ;
126
133
}
@@ -268,7 +275,7 @@ public void ReadFiles()
268
275
/// <returns></returns>
269
276
public int ShiftBuffers ( )
270
277
{
271
- _logger . Info ( "ShiftBuffers() begin for {0}{1}" , _fileName , IsMultiFile ? " (MultiFile)" : "" ) ;
278
+ _logger . Info ( "ShiftBuffers() begin for {0}{1}" , FileName , IsMultiFile ? " (MultiFile)" : "" ) ;
272
279
AcquireBufferListWriterLock ( ) ;
273
280
int offset = 0 ;
274
281
_isLineCountDirty = true ;
@@ -571,28 +578,142 @@ public int GetRealLineNumForVirtualLineNum(int lineNum)
571
578
return result ;
572
579
}
573
580
574
- public void StartMonitoring ( )
581
+ public async Task StartMonitoring ( )
575
582
{
576
- _logger . Info ( "startMonitoring()" ) ;
577
- _monitorTask = Task . Run ( MonitorThreadProc , cts . Token ) ;
583
+ _logger . Info ( "StartMonitoring() for file ${_watchedILogFileInfo.FullName}" ) ;
584
+
585
+ await Task . Run ( ( ) =>
586
+ {
587
+ _logger . Info ( "MonitorThreadProc() for file {0}" , _watchedILogFileInfo . FullName ) ;
588
+
589
+ long oldSize = 0 ;
590
+ try
591
+ {
592
+ OnLoadingStarted ( new LoadFileEventArgs ( FileName , 0 , false , 0 , false ) ) ;
593
+ ReadFiles ( ) ;
594
+ if ( ! _isDeleted )
595
+ {
596
+ oldSize = _fileLength ;
597
+ OnLoadingFinished ( ) ;
598
+ }
599
+ }
600
+ catch ( Exception e )
601
+ {
602
+ _logger . Error ( e ) ;
603
+ }
604
+ } ) ;
605
+
606
+ try
607
+ {
608
+ _watcher = new FileSystemWatcher
609
+ {
610
+ NotifyFilter = //NotifyFilters.Attributes
611
+ //| NotifyFilters.CreationTime
612
+ //| NotifyFilters.DirectoryName
613
+ //|
614
+ NotifyFilters . FileName
615
+ //| NotifyFilters.LastAccess
616
+ | NotifyFilters . LastWrite
617
+ //| NotifyFilters.Security
618
+ | NotifyFilters . Size ,
619
+
620
+ Path = Path . GetDirectoryName ( FileName ) ?? throw new ArgumentException ( "Invalid file path" ) ,
621
+ Filter = Path . GetFileName ( FileName ) , // Sets filter to the specific
622
+ EnableRaisingEvents = true
623
+ } ;
624
+ }
625
+ catch ( UnauthorizedAccessException ex )
626
+ {
627
+ Console . WriteLine ( $ "Access denied: { ex . Message } ") ;
628
+ }
629
+ catch ( ArgumentException ex )
630
+ {
631
+ Console . WriteLine ( $ "Invalid argument: { ex . Message } ") ;
632
+ }
633
+ catch ( Exception ex )
634
+ {
635
+ Console . WriteLine ( $ "An error occurred: { ex . Message } ") ;
636
+ }
637
+
638
+ _watcher . Error += ( sender , e ) =>
639
+ {
640
+ Console . WriteLine ( $ "Error occurred: { e . GetException ( ) . Message } ") ;
641
+ Task . Delay ( 5000 ) . ContinueWith ( _ =>
642
+ {
643
+ try
644
+ {
645
+ Console . WriteLine ( "Attempting to restart the watcher..." ) ;
646
+ _watcher . EnableRaisingEvents = true ;
647
+ }
648
+ catch ( Exception ex )
649
+ {
650
+ Console . WriteLine ( $ "Failed to restart the watcher: { ex . Message } ") ;
651
+ }
652
+ } ) ;
653
+ } ;
654
+ _watcher . Changed += OnFileChanged ;
655
+ _watcher . Created += OnCreated ;
656
+ _watcher . Deleted += OnFileDeleted ;
657
+ _watcher . Renamed += OnFileRenamed ;
658
+ _watcher . Error += OnFileError ;
659
+
578
660
_shouldStop = false ;
579
661
}
580
662
663
+ private void OnFileError ( object sender , ErrorEventArgs e )
664
+ {
665
+ throw new NotImplementedException ( ) ;
666
+ }
667
+
668
+ private void OnFileRenamed ( object sender , RenamedEventArgs e )
669
+ {
670
+ throw new NotImplementedException ( ) ;
671
+ }
672
+
673
+ private void OnCreated ( object sender , FileSystemEventArgs e )
674
+ {
675
+ //TODO: This should be deleted before merge?
676
+ throw new NotImplementedException ( ) ;
677
+ }
678
+
679
+ private void OnFileDeleted ( object sender , FileSystemEventArgs e )
680
+ {
681
+ MonitoredFileNotFound ( ) ;
682
+ }
683
+
684
+ private void OnFileChanged ( object sender , FileSystemEventArgs e )
685
+ {
686
+ try
687
+ {
688
+ _watchedILogFileInfo . FileHasChanged ( ) ;
689
+ _fileLength = _watchedILogFileInfo . Length ;
690
+ FileChanged ( ) ;
691
+ }
692
+ catch ( FileNotFoundException ex )
693
+ {
694
+ MonitoredFileNotFound ( ) ;
695
+ }
696
+ catch ( Exception ex )
697
+ {
698
+ throw new NotImplementedException ( ) ;
699
+ }
700
+ }
701
+
581
702
public void StopMonitoring ( )
582
703
{
583
704
_logger . Info ( "stopMonitoring()" ) ;
584
705
_shouldStop = true ;
585
706
586
- Thread . Sleep ( _watchedILogFileInfo . PollInterval ) ; // leave time for the threads to stop by themselves
587
-
588
- if ( _monitorTask != null )
707
+ if ( _watcher != null )
589
708
{
590
- if ( _monitorTask . Status == TaskStatus . Running ) // if thread has not finished, abort it
591
- {
592
- cts . Cancel ( ) ;
593
- }
709
+ _watcher . EnableRaisingEvents = false ; // Stop watching
710
+ _watcher . Dispose ( ) ; // Release resources
711
+ _watcher = null ; // Clear the reference
712
+
594
713
}
595
714
715
+ Thread . Sleep ( _watchedILogFileInfo . PollInterval ) ; // leave time for the threads to stop by themselves
716
+
596
717
if ( _garbageCollectorTask . IsCanceled == false )
597
718
{
598
719
if ( _garbageCollectorTask . Status == TaskStatus . Running ) // if thread has not finished, abort it
@@ -630,11 +751,11 @@ public void DeleteAllContent()
630
751
{
631
752
if ( _contentDeleted )
632
753
{
633
- _logger . Debug ( "Buffers for {0} already deleted." , Util . GetNameFromPath ( _fileName ) ) ;
754
+ _logger . Debug ( "Buffers for {0} already deleted." , Util . GetNameFromPath ( FileName ) ) ;
634
755
return ;
635
756
}
636
757
637
- _logger . Info ( "Deleting all log buffers for {0}. Used mem: {1:N0}" , Util . GetNameFromPath ( _fileName ) , GC . GetTotalMemory ( true ) ) ; //TODO [Z] uh GC collect calls creepy
758
+ _logger . Info ( "Deleting all log buffers for {0}. Used mem: {1:N0}" , Util . GetNameFromPath ( FileName ) , GC . GetTotalMemory ( true ) ) ; //TODO [Z] uh GC collect calls creepy
638
759
AcquireBufferListWriterLock ( ) ;
639
760
_lruCacheDictLock . AcquireWriterLock ( Timeout . Infinite ) ;
640
761
_disposeLock . AcquireWriterLock ( Timeout . Infinite ) ;
@@ -701,7 +822,7 @@ internal void LogBufferInfoForLine(int lineNum)
701
822
if ( buffer == null )
702
823
{
703
824
ReleaseBufferListReaderLock ( ) ;
704
- _logger . Error ( "Cannot find buffer for line {0}, file: {1}{2}" , lineNum , _fileName , IsMultiFile ? " (MultiFile)" : "" ) ;
825
+ _logger . Error ( "Cannot find buffer for line {0}, file: {1}{2}" , lineNum , FileName , IsMultiFile ? " (MultiFile)" : "" ) ;
705
826
return ;
706
827
}
707
828
@@ -726,7 +847,7 @@ internal void LogBufferDiagnostic()
726
847
_lruCacheDictLock . ReleaseReaderLock ( ) ;
727
848
728
849
AcquireBufferListReaderLock ( ) ;
729
- _logger . Info ( "File: {0}\r \n Buffer count: {1}\r \n Disposed buffers: {2}" , _fileName , _bufferList . Count , _bufferList . Count - cacheCount ) ;
850
+ _logger . Info ( "File: {0}\r \n Buffer count: {1}\r \n Disposed buffers: {2}" , FileName , _bufferList . Count , _bufferList . Count - cacheCount ) ;
730
851
int lineNum = 0 ;
731
852
long disposeSum = 0 ;
732
853
long maxDispose = 0 ;
@@ -782,7 +903,7 @@ private Task<ILogLine> GetLogLineInternal(int lineNum)
782
903
if ( logBuffer == null )
783
904
{
784
905
ReleaseBufferListReaderLock ( ) ;
785
- _logger . Error ( "Cannot find buffer for line {0}, file: {1}{2}" , lineNum , _fileName , IsMultiFile ? " (MultiFile)" : "" ) ;
906
+ _logger . Error ( "Cannot find buffer for line {0}, file: {1}{2}" , lineNum , FileName , IsMultiFile ? " (MultiFile)" : "" ) ;
786
907
return null ;
787
908
}
788
909
@@ -1147,7 +1268,7 @@ private void GarbageCollectLruCache()
1147
1268
#if DEBUG
1148
1269
if ( diff > 0 )
1149
1270
{
1150
- _logger . Info ( "Removing {0} entries from LRU cache for {1}" , diff , Util . GetNameFromPath ( _fileName ) ) ;
1271
+ _logger . Info ( "Removing {0} entries from LRU cache for {1}" , diff , Util . GetNameFromPath ( FileName ) ) ;
1151
1272
}
1152
1273
#endif
1153
1274
SortedList < long , int > useSorterList = [ ] ;
@@ -1464,74 +1585,6 @@ private LogBuffer GetFirstBufferForFileByLogBuffer(LogBuffer logBuffer)
1464
1585
return resultBuffer ;
1465
1586
}
1466
1587
1467
- private void MonitorThreadProc ( )
1468
- {
1469
- Thread . CurrentThread . Name = "MonitorThread" ;
1470
- //IFileSystemPlugin fs = PluginRegistry.GetInstance().FindFileSystemForUri(this.watchedILogFileInfo.FullName);
1471
- _logger . Info ( "MonitorThreadProc() for file {0}" , _watchedILogFileInfo . FullName ) ;
1472
-
1473
- long oldSize = 0 ;
1474
- try
1475
- {
1476
- OnLoadingStarted ( new LoadFileEventArgs ( _fileName , 0 , false , 0 , false ) ) ;
1477
- ReadFiles ( ) ;
1478
- if ( ! _isDeleted )
1479
- {
1480
- oldSize = _fileLength ;
1481
- OnLoadingFinished ( ) ;
1482
- }
1483
- }
1484
- catch ( Exception e )
1485
- {
1486
- _logger . Error ( e ) ;
1487
- }
1488
-
1489
- while ( ! _shouldStop )
1490
- {
1491
- try
1492
- {
1493
- int pollInterval = _watchedILogFileInfo . PollInterval ;
1494
- //#if DEBUG
1495
- // if (_logger.IsDebug)
1496
- // {
1497
- // _logger.logDebug("Poll interval for " + this.fileName + ": " + pollInterval);
1498
- // }
1499
- //#endif
1500
- Thread . Sleep ( pollInterval ) ;
1501
- }
1502
- catch ( Exception e )
1503
- {
1504
- _logger . Error ( e ) ;
1505
- }
1506
-
1507
- if ( _shouldStop )
1508
- {
1509
- return ;
1510
- }
1511
-
1512
- try
1513
- {
1514
- if ( _watchedILogFileInfo . FileHasChanged ( ) )
1515
- {
1516
- _fileLength = _watchedILogFileInfo . Length ;
1517
- if ( _fileLength == - 1 )
1518
- {
1519
- MonitoredFileNotFound ( ) ;
1520
- }
1521
- else
1522
- {
1523
- oldSize = _fileLength ;
1524
- FileChanged ( ) ;
1525
- }
1526
- }
1527
- }
1528
- catch ( FileNotFoundException )
1529
- {
1530
- MonitoredFileNotFound ( ) ;
1531
- }
1532
- }
1533
- }
1534
-
1535
1588
private void MonitoredFileNotFound ( )
1536
1589
{
1537
1590
long oldSize ;
@@ -1563,7 +1616,7 @@ private void FileChanged()
1563
1616
long newSize = _fileLength ;
1564
1617
//if (this.currFileSize != newSize)
1565
1618
{
1566
- _logger . Info ( "file size changed. new size={0}, file: {1}" , newSize , _fileName ) ;
1619
+ _logger . Info ( "file size changed. new size={0}, file: {1}" , newSize , FileName ) ;
1567
1620
FireChangeEvent ( ) ;
1568
1621
}
1569
1622
}
@@ -1586,7 +1639,7 @@ private void FireChangeEvent()
1586
1639
{
1587
1640
// ReloadBufferList(); // removed because reloading is triggered by owning LogWindow
1588
1641
// Trigger "new file" handling (reload)
1589
- OnLoadFile ( new LoadFileEventArgs ( _fileName , 0 , true , _fileLength , true ) ) ;
1642
+ OnLoadFile ( new LoadFileEventArgs ( FileName , 0 , true , _fileLength , true ) ) ;
1590
1643
1591
1644
if ( _isDeleted )
1592
1645
{
0 commit comments