42 lines
2.0 KiB
C#
42 lines
2.0 KiB
C#
using ItWorx.KnowledgeHub.Application.Operations;
|
|
|
|
namespace ItWorx.KnowledgeHub.Api.BackgroundServices;
|
|
|
|
public sealed partial class OperationalTelemetryBackgroundService(
|
|
IServiceScopeFactory scopeFactory, PlatformMetrics metrics, TimeProvider clock,
|
|
ILogger<OperationalTelemetryBackgroundService> logger) : BackgroundService
|
|
{
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
// Do not race initial database migration during host startup.
|
|
await Task.Delay(TimeSpan.FromSeconds(30), clock, stoppingToken);
|
|
using var scope = scopeFactory.CreateScope();
|
|
var snapshot = await scope.ServiceProvider.GetRequiredService<IOperationalTelemetryReader>()
|
|
.ReadAsync(stoppingToken);
|
|
var now = clock.GetUtcNow();
|
|
metrics.SetQueueState(snapshot.QueuedJobs, snapshot.RunningJobs, snapshot.FailedJobs,
|
|
Age(snapshot.OldestQueuedJobAt, now));
|
|
metrics.SetOperationalAges(Age(snapshot.OldestPendingIngestionAt, now),
|
|
Age(snapshot.LatestInventoryCaptureAt, now), Age(snapshot.LatestVerifiedBackupAt, now));
|
|
}
|
|
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { break; }
|
|
catch (Exception)
|
|
{
|
|
// Omit stale gauges after a failed read, rather than exporting old success.
|
|
metrics.ClearSnapshots();
|
|
LogReadFailed();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static double? Age(DateTimeOffset? value, DateTimeOffset now) =>
|
|
value is { } time && time <= now ? (now - time).TotalSeconds : null;
|
|
|
|
[LoggerMessage(Level = LogLevel.Warning, Message = "Operationele metriekmeting mislukt; waarden blijven onbekend tot de volgende geslaagde meting.")]
|
|
private partial void LogReadFailed();
|
|
}
|