142 lines
4.4 KiB
C#
142 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace InstallMonitor
|
|
{
|
|
public class LogReader
|
|
{
|
|
private CancellationTokenSource _cts;
|
|
private ConfigService _configService;
|
|
private long _lastPosition = 0;
|
|
private int _retryCount = 0;
|
|
public LogReader(ConfigService config, CancellationTokenSource cts)
|
|
{
|
|
_configService = config;
|
|
_cts = cts;
|
|
}
|
|
|
|
public string Directory => _configService.Settings.LogFileDirectory;
|
|
public string FilePattern => _configService.Settings.LogFileNamePattern;
|
|
public int MaxRetries => _configService.Settings.MaxRetries;
|
|
public int RetryTimeout => _configService.Settings.RetryTimeout;
|
|
public string LogFile { get; private set; } = string.Empty;
|
|
|
|
public event EventHandler? InternalError;
|
|
public event EventHandler? ReadLine;
|
|
public event EventHandler? StreamOpen;
|
|
public event EventHandler? AwaitLine;
|
|
public event EventHandler? TaskFailed;
|
|
|
|
private void FindLogFile()
|
|
{
|
|
var file = new DirectoryInfo(Directory)
|
|
.GetFiles(FilePattern)
|
|
.OrderByDescending(f => f.Name)
|
|
.FirstOrDefault();
|
|
|
|
if (file != null)
|
|
{
|
|
LogFile = file.FullName;
|
|
}
|
|
|
|
if (!File.Exists(LogFile))
|
|
throw new IOException("Datei nicht gefunden");
|
|
|
|
}
|
|
|
|
public async Task ReadLogAsync()
|
|
{
|
|
while (!_cts.Token.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
FindLogFile();
|
|
|
|
using var fs = new FileStream(LogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
using var reader = new StreamReader(fs, System.Text.Encoding.UTF8, true);
|
|
|
|
StreamOpened();
|
|
|
|
if (_lastPosition == 0)
|
|
{
|
|
string? line;
|
|
while ((line = await reader.ReadLineAsync()) != null)
|
|
{
|
|
LineRead(line);
|
|
}
|
|
_lastPosition = fs.Position;
|
|
}
|
|
|
|
while (!_cts.IsCancellationRequested)
|
|
{
|
|
fs.Seek(_lastPosition, SeekOrigin.Begin);
|
|
|
|
string? line;
|
|
while ((line = await reader.ReadLineAsync()) != null)
|
|
{
|
|
LineRead(line);
|
|
}
|
|
|
|
_lastPosition = fs.Position;
|
|
await Task.Delay(200, _cts.Token);
|
|
|
|
LineAwaited();
|
|
}
|
|
}
|
|
catch (OperationCanceledException ex) { }
|
|
catch (Exception ex) when (_retryCount < MaxRetries)
|
|
{
|
|
InternalErrorCaught($"Versuch: ({_retryCount + 1}/{MaxRetries}) - {ex.Message}");
|
|
_retryCount++;
|
|
await Task.Delay(RetryTimeout, _cts.Token);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
TaskHasFailed($"Versuch: (no more retries) - {ex.Message}");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void StreamOpened()
|
|
{
|
|
_retryCount = 0;
|
|
|
|
var handle = StreamOpen;
|
|
if(handle != null)
|
|
handle.Invoke(null, EventArgs.Empty);
|
|
}
|
|
|
|
public void LineRead(string line)
|
|
{
|
|
var handle = ReadLine;
|
|
if (handle != null)
|
|
handle.Invoke(line, EventArgs.Empty);
|
|
}
|
|
|
|
public void LineAwaited()
|
|
{
|
|
var handle = AwaitLine;
|
|
if (handle != null)
|
|
handle.Invoke(null, EventArgs.Empty);
|
|
}
|
|
|
|
public void InternalErrorCaught(string message)
|
|
{
|
|
var handle = InternalError;
|
|
if (handle != null)
|
|
handle.Invoke(message, EventArgs.Empty);
|
|
}
|
|
|
|
public void TaskHasFailed(string message)
|
|
{
|
|
var handle = InternalError;
|
|
if (handle != null)
|
|
handle.Invoke(message, EventArgs.Empty);
|
|
}
|
|
}
|
|
}
|