hacompanion/HaCompanion/UptimePollerService.cs
Erki 4d7ac3e5c3
Some checks failed
Build and push latest / publish (push) Failing after 1m28s
Initial
2025-03-29 20:32:58 +02:00

111 lines
3.9 KiB
C#

namespace HaCompanion;
class StatisticsHolder
{
public string name;
public string url;
public string requestPath;
public UptimeStatistics? latestResult;
}
public class UptimePollerService : IHostedService
{
private readonly int _interval;
private Timer _timer;
private List<StatisticsHolder> _uptimeStatistics = new List<StatisticsHolder>();
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<UptimePollerService> _logger;
public UptimePollerService(IConfiguration configuration, IHttpClientFactory httpClientFactory, ILogger<UptimePollerService> logger)
{
_httpClientFactory = httpClientFactory;
_logger = logger;
_interval = configuration.GetRequiredSection("Uptime").GetValue<int>("Period") * 60_000;
var statsEntries = configuration.GetRequiredSection("Uptime").GetRequiredSection("Websites").GetChildren();
foreach (var entry in statsEntries)
{
var holder = new StatisticsHolder()
{
name = entry.GetRequiredSection("website").Value!,
url = entry.GetRequiredSection("BaseUrl").Value!,
requestPath = entry.GetRequiredSection("RequestUrl").Value!,
latestResult = null
};
_logger.LogDebug("Added stats entry {Name}", holder.name);
_uptimeStatistics.Add(holder);
}
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogDebug("Starting async.");
await OnTimerFiredAsync();
_timer = new Timer(async _ => await OnTimerFiredAsync(),
null, _interval, Timeout.Infinite);
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogDebug("Stopping async.");
_timer?.Dispose();
return Task.CompletedTask;
}
public List<UptimeStatistics> GetUptimeStatistics()
{
var result = new List<UptimeStatistics>();
foreach (var statistics in _uptimeStatistics)
{
result.Add(statistics.latestResult);
}
return result;
}
private async Task OnTimerFiredAsync()
{
_logger.LogInformation("Executing HTTP status checks.");
try
{
foreach (var holder in _uptimeStatistics)
{
_logger.LogDebug("{Name} - Checking uptime.", holder.name);
try
{
var client = _httpClientFactory.CreateClient(holder.name);
var response = await client.GetAsync(holder.requestPath);
if (!response.IsSuccessStatusCode)
{
holder.latestResult = new UptimeStatistics(holder.name, true, false, null);
_logger.LogWarning("{Name} - HTTP failed. Status code: {Code}", holder.name, response.StatusCode);
}
else
{
holder.latestResult = new UptimeStatistics(holder.name, true, true, true);
_logger.LogDebug("{Name} - HTTP success.", holder.name);
}
}
catch (HttpRequestException he)
{
holder.latestResult = new UptimeStatistics(holder.name, false, null, null);
_logger.LogWarning("{Name} - HTTP failed with HttpRequestException. {Ex}", holder.name, he);
}
catch (Exception e)
{
holder.latestResult = new UptimeStatistics(holder.name, false, null, null);
_logger.LogError("{Name} - HTTP failed with general Exception. {Ex}", holder.name, e);
}
}
}
finally
{
_logger.LogDebug("HTTP status checks completed.");
_timer?.Change(_interval, Timeout.Infinite);
}
}
}