Add new health
This commit is contained in:
114
src/Managing.Api/HealthChecks/CandleDataHealthCheck.cs
Normal file
114
src/Managing.Api/HealthChecks/CandleDataHealthCheck.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using Managing.Application.Abstractions.Services;
|
||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Api.HealthChecks
|
||||
{
|
||||
public class CandleDataHealthCheck : IHealthCheck
|
||||
{
|
||||
private readonly IExchangeService _exchangeService;
|
||||
private readonly Ticker _tickerToCheck = Ticker.ETH;
|
||||
private readonly TradingExchanges _exchangeToCheck = TradingExchanges.Evm;
|
||||
|
||||
public CandleDataHealthCheck(IExchangeService exchangeService)
|
||||
{
|
||||
_exchangeService = exchangeService;
|
||||
}
|
||||
|
||||
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
// Define timeframes to check with their appropriate start dates and expected freshness
|
||||
var timeframeChecks = new[]
|
||||
{
|
||||
(timeframe: Timeframe.FifteenMinutes, startDate: now.AddDays(-1), maxAgeMins: 30.0),
|
||||
(timeframe: Timeframe.OneHour, startDate: now.AddDays(-3), maxAgeMins: 120.0),
|
||||
(timeframe: Timeframe.OneDay, startDate: now.AddDays(-30), maxAgeMins: 1440.0)
|
||||
};
|
||||
|
||||
var results = new List<Dictionary<string, object>>();
|
||||
var isHealthy = true;
|
||||
|
||||
foreach (var (timeframe, startDate, maxAgeMins) in timeframeChecks)
|
||||
{
|
||||
// Using configured exchange and ticker
|
||||
var candles = await _exchangeService.GetCandlesInflux(
|
||||
_exchangeToCheck,
|
||||
_tickerToCheck,
|
||||
startDate,
|
||||
timeframe);
|
||||
|
||||
var checkResult = new Dictionary<string, object>
|
||||
{
|
||||
["CheckedTicker"] = _tickerToCheck.ToString(),
|
||||
["CheckedTimeframe"] = timeframe.ToString(),
|
||||
["StartDate"] = startDate
|
||||
};
|
||||
|
||||
if (candles == null || !candles.Any())
|
||||
{
|
||||
checkResult["Status"] = "Degraded";
|
||||
checkResult["Message"] = $"No candle data found for {timeframe}";
|
||||
isHealthy = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var latestCandle = candles.OrderByDescending(c => c.Date).FirstOrDefault();
|
||||
var timeDiff = now - latestCandle.Date;
|
||||
|
||||
checkResult["LatestCandleDate"] = latestCandle.Date;
|
||||
checkResult["TimeDifference"] = $"{timeDiff.TotalMinutes:F2} minutes";
|
||||
|
||||
if (timeDiff.TotalMinutes > maxAgeMins)
|
||||
{
|
||||
checkResult["Status"] = "Degraded";
|
||||
checkResult["Message"] = $"Data for {timeframe} is outdated. Latest candle is from {latestCandle.Date:yyyy-MM-dd HH:mm:ss} UTC";
|
||||
isHealthy = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkResult["Status"] = "Healthy";
|
||||
checkResult["Message"] = $"Data for {timeframe} is up-to-date. Latest candle is from {latestCandle.Date:yyyy-MM-dd HH:mm:ss} UTC";
|
||||
}
|
||||
}
|
||||
|
||||
results.Add(checkResult);
|
||||
}
|
||||
|
||||
// Combine all results into a summary
|
||||
var resultsDictionary = new Dictionary<string, object>();
|
||||
for (int i = 0; i < results.Count; i++)
|
||||
{
|
||||
resultsDictionary[$"TimeframeCheck_{i+1}"] = results[i];
|
||||
}
|
||||
|
||||
if (isHealthy)
|
||||
{
|
||||
return HealthCheckResult.Healthy(
|
||||
"All candle timeframes are up-to-date",
|
||||
data: resultsDictionary);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HealthCheckResult.Degraded(
|
||||
"One or more candle timeframes are outdated or missing",
|
||||
data: resultsDictionary);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return HealthCheckResult.Unhealthy(
|
||||
"Error checking candle data health",
|
||||
ex,
|
||||
data: new Dictionary<string, object>
|
||||
{
|
||||
["ErrorMessage"] = ex.Message,
|
||||
["ErrorType"] = ex.GetType().Name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user