114 lines
4.8 KiB
C#
114 lines
4.8 KiB
C#
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
|
|
});
|
|
}
|
|
}
|
|
}
|
|
} |