< Summary

Information
Class: OzonOrdersWeb.WebServices.SystemAlerts.SystemAlertTelegramNotifier
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/SystemAlerts/SystemAlertTelegramNotifier.cs
Line coverage
18%
Covered lines: 9
Uncovered lines: 40
Coverable lines: 49
Total lines: 77
Line coverage: 18.3%
Branch coverage
22%
Covered branches: 5
Total branches: 22
Branch coverage: 22.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
.cctor()100%210%
NotifyAsync()0%4260%
ToItems(...)0%4260%
DomainLabel(...)0%620%
ToItems(...)50%8663.63%
IsDirectOneCEvent(...)100%22100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/SystemAlerts/SystemAlertTelegramNotifier.cs

#LineLine coverage
 1using OzonOrdersWeb.WebServices.JobLogs;
 2using Services.ApiServices.TelegramBotApi;
 3
 4namespace OzonOrdersWeb.WebServices.SystemAlerts;
 5
 6/// <summary>
 7/// Отправляет в Telegram изменения системных алертов (вкладка «Алерты» в JobLogs): появление и эскалацию ошибок
 8/// и предупреждений, а также восстановление. Информационные алерты в чат не уходят.
 9/// </summary>
 010public sealed class SystemAlertTelegramNotifier(ITelegramNotifier telegram, TelegramBotConfig config,
 011    ILogger<SystemAlertTelegramNotifier> logger)
 12{
 013    private static readonly Dictionary<string, string> DomainLabels = new(StringComparer.OrdinalIgnoreCase)
 014    {
 015        ["hangfire"] = "Hangfire",
 016        ["onec"] = "1С",
 017        ["orders"] = "Заказы",
 018        ["ozon"] = "Ozon",
 019        ["search"] = "Поиск",
 020        ["stock"] = "Остатки",
 021        ["suppliers"] = "Поставщики",
 022        ["monitoring"] = "Мониторинг",
 023        ["server"] = "Сервер",
 024        ["database"] = "База данных",
 025        ["integration"] = "Интеграции",
 026        ["ordercontrol"] = "Контроль заказов"
 027    };
 28
 29    public async Task NotifyAsync(IReadOnlyList<SystemAlertTransition> transitions, CancellationToken cancellationToken 
 30    {
 031        if (!telegram.IsConfigured) return;
 32
 033        var items = ToItems(transitions);
 034        if (items.Count == 0) return;
 35
 36        try
 37        {
 038            foreach (var message in TelegramMessageFactory.AlertDigest(items, config.SiteBaseUrl))
 039                await telegram.SendAsync(message, cancellationToken);
 040        }
 041        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
 42        {
 043            throw;
 44        }
 045        catch (Exception ex)
 46        {
 047            logger.LogWarning(ex, "Не удалось отправить сводку системных алертов в Telegram");
 048        }
 049    }
 50
 51    /// <summary>Действующие алерты (из вкладки «Алерты») для закреплённого сообщения; информационные не включаются.</su
 052    public static IReadOnlyList<TelegramAlertItem> ToItems(IEnumerable<JobLogsSystemAlertDto> active) => active
 053        .Where(x => x.Severity is "danger" or "warning")
 054        .Select(x => new TelegramAlertItem(
 055            x.Severity == "danger" ? TelegramSeverity.Critical : TelegramSeverity.Warning,
 056            DomainLabel(x.Domain), x.Title, x.Lines, x.Url))
 057        .ToList();
 58
 59    private static string DomainLabel(string domain) =>
 060        DomainLabels.GetValueOrDefault(domain, string.IsNullOrWhiteSpace(domain) ? "Система" : domain);
 61
 262    public static IReadOnlyList<TelegramAlertItem> ToItems(IEnumerable<SystemAlertTransition> transitions) => transition
 263        .Where(x => x.Severity is "danger" or "warning")
 264        // Номенклатура и подтверждённый дефицит отправляют отдельное сообщение сразу в тему 1С.
 265        // Инцидент всё равно остаётся в JobLogs и в закреплённом сообщении, но не должен дублироваться
 266        // общим пятиминутным дайджестом в теме системных алертов.
 267        .Where(x => !IsDirectOneCEvent(x.Title))
 068        .Select(x => new TelegramAlertItem(
 069            x.Severity == "danger" ? TelegramSeverity.Critical : TelegramSeverity.Warning,
 070            DomainLabel(x.Domain),
 071            x.Title, x.Lines, x.Url, x.OrderCount, x.Resolved))
 272        .ToList();
 73
 74    private static bool IsDirectOneCEvent(string title) =>
 275        title.Contains("номенклатур", StringComparison.OrdinalIgnoreCase)
 276        || title.Contains("нехватка остатка перед проведением", StringComparison.OrdinalIgnoreCase);
 77}