63 lines
2.8 KiB
C#
63 lines
2.8 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace ScadaLink.HealthMonitoring;
|
|
|
|
public static class ServiceCollectionExtensions
|
|
{
|
|
/// <summary>
|
|
/// Register site-side health monitoring services (metric collection + periodic reporting).
|
|
/// Call this on site nodes only. For central, call AddCentralHealthAggregation() instead.
|
|
/// </summary>
|
|
public static IServiceCollection AddSiteHealthMonitoring(this IServiceCollection services)
|
|
{
|
|
AddOptionsValidation(services);
|
|
services.AddSingleton<ISiteHealthCollector, SiteHealthCollector>();
|
|
services.AddHostedService<HealthReportSender>();
|
|
return services;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register shared health monitoring services (safe for both central and site).
|
|
/// Does not start the HealthReportSender — call AddSiteHealthMonitoring() on site nodes for that.
|
|
/// </summary>
|
|
public static IServiceCollection AddHealthMonitoring(this IServiceCollection services)
|
|
{
|
|
AddOptionsValidation(services);
|
|
services.AddSingleton<ISiteHealthCollector, SiteHealthCollector>();
|
|
return services;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register central-side health aggregation services. Includes the
|
|
/// <see cref="CentralHealthReportLoop"/> that generates a self-report
|
|
/// for the central cluster so it appears on /monitoring/health.
|
|
/// </summary>
|
|
public static IServiceCollection AddCentralHealthAggregation(this IServiceCollection services)
|
|
{
|
|
AddOptionsValidation(services);
|
|
services.AddSingleton<CentralHealthAggregator>();
|
|
services.AddSingleton<ICentralHealthAggregator>(sp => sp.GetRequiredService<CentralHealthAggregator>());
|
|
services.AddHostedService(sp => sp.GetRequiredService<CentralHealthAggregator>());
|
|
services.AddHostedService<CentralHealthReportLoop>();
|
|
return services;
|
|
}
|
|
|
|
/// <summary>
|
|
/// HealthMonitoring-014: register the <see cref="HealthMonitoringOptionsValidator"/>
|
|
/// so a misconfigured <c>ScadaLink:HealthMonitoring</c> section (zero/negative
|
|
/// intervals, or a <c>CentralOfflineTimeout</c> shorter than
|
|
/// <c>OfflineTimeout</c>) is rejected with a clear, key-naming message when the
|
|
/// hosted services resolve their options at startup — rather than crashing
|
|
/// later inside a <see cref="PeriodicTimer"/> constructor with an opaque
|
|
/// <see cref="ArgumentOutOfRangeException"/>. Idempotent so it is safe when
|
|
/// more than one of the registration methods above is called.
|
|
/// </summary>
|
|
private static void AddOptionsValidation(IServiceCollection services)
|
|
{
|
|
services.TryAddEnumerable(
|
|
ServiceDescriptor.Singleton<IValidateOptions<HealthMonitoringOptions>, HealthMonitoringOptionsValidator>());
|
|
}
|
|
}
|