Solo.Beacon 1.0.3-pre01

Solo.Beacon

Solo.Beacon — это переиспользуемый ASP.NET Core пакет для сервисов ft-soft. Он предоставляет:

  • endpoint /beacon/discovery, который публикует пути health и stats текущего сервиса
  • endpoint /health, который отвечает 200 OK на любой HTTP-метод и содержит ссылку на endpoint статистики
  • endpoint /stats для состояния текущего сервиса
  • общий флаг логирования запросов к /beacon/discovery, /health и /stats
  • опциональный фоновый опрос зависимых сервисов с обработкой результатов через delegate
  • стартовую health-проверку зависимостей сразу после запуска приложения

Быстрый старт

using Solo.Beacon;
using Solo.Beacon.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddBeacon();

var app = builder.Build();

app.MapBeacon()
    .MapHealth();

MapBeacon() всегда регистрирует /beacon/discovery и fallback /stats, который отвечает 200 OK с No stats. MapHealth() нужен только при необходимости в кастомном роуте. MapStats(...) нужен только если сервису требуется собственный ответ статистики.

Где настраивать пути

Пути к health и stats можно задавать в трех местах. Это сделано для разных сценариев:

  • дефолты пакета — подходят, когда сервису достаточно /health и /stats
  • секция Beacon в конфиге — основной способ для приложений, где пути должны меняться без правки Program.cs
  • параметры MapHealth(...) и MapStats(...) — точечное переопределение маршрута рядом с регистрацией endpoint-а

Приоритет такой:

  1. url, переданный прямо в MapHealth(url) или MapStats(handler, url).
  2. BeaconOptions.HealthUrl / BeaconOptions.StatsUrl, полученные из AddBeacon(...).
  3. дефолтные пути /health и /stats.

Самый высокий приоритет у параметров MapHealth(...) и MapStats(...), потому что они одновременно регистрируют конкретный route в ASP.NET Core и обновляют значение, которое отдается через discovery.

app.MapBeacon()
    .MapHealth("/internal/health")
    .MapStats(GetStatsAsync, "/internal/stats");

В этом примере /beacon/discovery вернет /internal/health и /internal/stats, даже если в конфиге указаны другие значения HealthUrl и StatsUrl.

Рекомендация

Для большинства сервисов лучше хранить пути в конфиге и не передавать url в MapHealth(...) / MapStats(...). Так настройка остается одинаковой для разных окружений и не требует отдельной правки кода:

{
  "Beacon": {
    "LoggingEnabled": false,
    "HealthUrl": "/health",
    "StatsUrl": "/stats"
  }
}
builder.Services.AddBeacon();

app.MapBeacon()
    .MapHealth()
    .MapStats(GetStatsAsync);

Передавайте url прямо в MapHealth(...) или MapStats(...), когда путь является частью кода конкретного приложения: например, endpoint должен жить под уже существующим /internal/*, рядом с reverse proxy rules или legacy routing.

Конфигурация через код

Если настройки нельзя брать из IConfiguration, используйте перегрузку с Action<BeaconOptions>:

builder.Services.AddBeacon(options =>
{
    options.LoggingEnabled = true;
    options.HealthUrl = "/health";
    options.StatsUrl = "/stats";
});

Эта перегрузка настраивает BeaconOptions из кода. Если нужен обычный appsettings.json, используйте builder.Services.AddBeacon() без lambda.

Stats

/stats регистрируется уже в MapBeacon(). Если MapStats(...) не вызван, endpoint отвечает 200 OK с текстом No stats.

/health отвечает 200 OK с Healthy и HTML-ссылкой на текущий endpoint статистики, например <a href="/stats">Статистика</a>. Если путь статистики переопределен через конфиг или MapStats(..., url), ссылка указывает на переопределенный путь.

Если нужен собственный ответ /stats, передайте async-handler в MapStats(...). В нем доступны HttpContext и CancellationToken, поэтому состав статистики можно настраивать в зависимости от пользователя, заголовков и других деталей запроса.

app.MapBeacon()
    .MapHealth()
    .MapStats(async (httpContext, cancellationToken) =>
    {
        var statsProvider = httpContext.RequestServices.GetRequiredService<StatsProvider>();
        var stats = await statsProvider.GetStatsAsync(cancellationToken);
        var userName = httpContext.User.Identity?.Name;

        return TypedResults.Ok(new
        {
            stats,
            userName,
        });
    });

Пользовательский /stats, подключенный через MapStats(...), закрыт авторизацией и использует стандартные сервисы авторизации ASP.NET Core из хост-приложения. Чтобы в HttpContext.User были данные пользователя, хост-приложение должно само настроить аутентификацию обычным для себя способом. Fallback-ответ No stats авторизацию не требует.

Мониторинг зависимостей

{
  "Beacon": {
    "LoggingEnabled": false,
    "HealthUrl": "/health",
    "StatsUrl": "/stats",
    "Monitoring": {
      "Enabled": true,
      "ProbeInterval": "00:00:30",
      "RequestTimeout": "00:00:05",
      "Services": [
        "https://solo-butler.ru",
        "https://solo.ru/solo",
        "https://solo.ru/org"
      ]
    }
  }
}

Если мониторинг включен, пакет сразу после старта приложения делает первый проход по Services: запрашивает у каждого сервиса /discovery, находит опубликованный health endpoint и проверяет его доступность. Дальше проверки повторяются с интервалом ProbeInterval.

Если нужно обработать результаты мониторинга зависимостей, настройте handler через BeaconBuilder:

builder.Services
    .AddBeacon()
    .AddMonitoringHandler(
        static async (serviceProvider, responses, cancellationToken) =>
        {
            var cache = serviceProvider.GetRequiredService<IMonitoringCache>();
            await cache.StoreAsync(responses, cancellationToken);
        });

Успешные проверки и ошибки пишутся в лог только при LoggingEnabled = true.

Discovery

/discovery всегда находится на фиксированном пути и не настраивается через конфиг. Мониторинг зависимостей полагается именно на этот адрес, чтобы сначала узнать реальные пути health и stats у сервиса, а затем проверить опубликованный health endpoint.

Если зависимый сервис возвращает 404 Not Found на /discovery, это трактуется как отсутствие поддержки Solo.Beacon. Если health endpoint зависимого сервиса возвращает не JSON, Solo.Beacon сформирует служебный payload со статусом проверки.

No packages depend on Solo.Beacon.

Version Downloads Last updated
1.0.6 2 08/04/2026
1.0.5 28 08/03/2026
1.0.3 245 07/21/2026
1.0.3-pre01 1 07/21/2026
1.0.2 29 07/20/2026
1.0.2-pre03 1 07/20/2026
1.0.2-pre02 1 07/20/2026
1.0.2-pre01 1 07/20/2026
1.0.1 1 07/20/2026
1.0.0 6 05/28/2026
1.0.0-pre-doc4847-07 5 05/19/2026
1.0.0-pre-doc4847-06 5 05/19/2026
1.0.0-pre-doc4847-05 5 05/19/2026
1.0.0-pre-doc4847-04 5 05/19/2026
1.0.0-pre-doc4847-03 5 05/18/2026
1.0.0-pre-doc4847-02 5 05/18/2026
1.0.0-pre-doc4847-01 5 05/18/2026