< Summary

Information
Class: OzonOrdersWeb.Observability.ApplicationReadyHealthCheck
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Observability/ApplicationReadyHealthCheck.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 30
Coverable lines: 30
Total lines: 67
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
CheckHealthAsync()0%7280%
CanConnectAsync()100%210%
GetFreeDiskBytes()0%620%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Observability/ApplicationReadyHealthCheck.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore;
 2using Microsoft.Extensions.Diagnostics.HealthChecks;
 3using OzonRepositories.Context;
 4
 5namespace OzonOrdersWeb.Observability;
 6
 07public sealed class ApplicationReadyHealthCheck(IServiceScopeFactory scopeFactory) : IHealthCheck
 8{
 9    public async Task<HealthCheckResult> CheckHealthAsync(
 10        HealthCheckContext context,
 11        CancellationToken cancellationToken = default)
 12    {
 13        try
 14        {
 015            await using var scope = scopeFactory.CreateAsyncScope();
 016            var primary = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
 017            if (!await primary.Database.CanConnectAsync(cancellationToken))
 18            {
 019                return HealthCheckResult.Unhealthy("Основная база данных недоступна");
 20            }
 21
 022            var ozonApi = scope.ServiceProvider.GetRequiredService<OzonApiContext>();
 023            var bitrix = scope.ServiceProvider.GetRequiredService<BitrixContext>();
 024            var optionalDependencies = new Dictionary<string, object>
 025            {
 026                ["OzonApiDatabase"] = await CanConnectAsync(ozonApi, cancellationToken),
 027                ["BitrixDatabase"] = await CanConnectAsync(bitrix, cancellationToken),
 028                ["FreeDiskBytes"] = GetFreeDiskBytes()
 029            };
 030            var freeDiskBytes = (long)optionalDependencies["FreeDiskBytes"];
 031            if (freeDiskBytes < 1L * 1024 * 1024 * 1024)
 32            {
 033                return HealthCheckResult.Unhealthy("На диске осталось менее 1 ГБ", data: optionalDependencies);
 34            }
 35
 036            if (optionalDependencies.Values.Take(2).OfType<bool>().Any(available => !available)
 037                || freeDiskBytes < 5L * 1024 * 1024 * 1024)
 38            {
 039                return HealthCheckResult.Degraded("Основная БД доступна, но одна из необязательных зависимостей деградир
 40            }
 41
 042            return HealthCheckResult.Healthy("Критичные зависимости доступны", optionalDependencies);
 043        }
 044        catch (Exception exception)
 45        {
 046            return HealthCheckResult.Unhealthy("Ошибка проверки основной базы данных", exception);
 47        }
 048    }
 49
 50    private static async Task<bool> CanConnectAsync(DbContext db, CancellationToken cancellationToken)
 51    {
 52        try
 53        {
 054            return await db.Database.CanConnectAsync(cancellationToken);
 55        }
 056        catch
 57        {
 058            return false;
 59        }
 060    }
 61
 62    private static long GetFreeDiskBytes()
 63    {
 064        var root = Path.GetPathRoot(AppContext.BaseDirectory) ?? "/";
 065        return new DriveInfo(root).AvailableFreeSpace;
 66    }
 67}