diff --git a/main.go b/main.go index 07542f9..808a008 100644 --- a/main.go +++ b/main.go @@ -425,8 +425,8 @@ func (b *bot) handleHealth(ctx context.Context, chatID int64) error { if err := b.callTelemt(ctx, "/v1/health", &h); err != nil { return b.sendMessage(ctx, chatID, "Ошибка API: "+err.Error()) } - msg := fmt.Sprintf("Health: %s\nRead-only: %t", h.Status, h.ReadOnly) - return b.sendMessage(ctx, chatID, msg) + text := buildHealthMessageHTML(h) + return b.sendMessageWithKeyboardHTML(ctx, chatID, text, backKeyboard(), true) } func (b *bot) handleSummary(ctx context.Context, chatID int64) error { @@ -434,11 +434,8 @@ func (b *bot) handleSummary(ctx context.Context, chatID int64) error { if err := b.callTelemt(ctx, "/v1/stats/summary", &s); err != nil { return b.sendMessage(ctx, chatID, "Ошибка API: "+err.Error()) } - msg := fmt.Sprintf( - "Uptime: %.0fs\nConn total: %d\nConn bad: %d\nHandshake timeouts: %d\nUsers: %d", - s.UptimeSeconds, s.ConnectionsTotal, s.ConnectionsBadTotal, s.HandshakeTimeoutsTotal, s.ConfiguredUsers, - ) - return b.sendMessage(ctx, chatID, msg) + text := buildSummaryMessageHTML(s) + return b.sendMessageWithKeyboardHTML(ctx, chatID, text, backKeyboard(), true) } func (b *bot) handleUsers(ctx context.Context, chatID int64) error { @@ -678,8 +675,8 @@ func (b *bot) handleHealthCB(ctx context.Context, chatID, msgID int64) error { if err := b.callTelemt(ctx, "/v1/health", &h); err != nil { return b.editMessageText(ctx, chatID, msgID, "Ошибка API: "+err.Error(), backKeyboard()) } - msg := fmt.Sprintf("Health: %s\nRead-only: %t", h.Status, h.ReadOnly) - return b.editMessageText(ctx, chatID, msgID, msg, backKeyboard()) + text := buildHealthMessageHTML(h) + return b.editMessageTextHTML(ctx, chatID, msgID, text, backKeyboard(), true) } func (b *bot) handleSummaryCB(ctx context.Context, chatID, msgID int64) error { @@ -687,11 +684,8 @@ func (b *bot) handleSummaryCB(ctx context.Context, chatID, msgID int64) error { if err := b.callTelemt(ctx, "/v1/stats/summary", &s); err != nil { return b.editMessageText(ctx, chatID, msgID, "Ошибка API: "+err.Error(), backKeyboard()) } - msg := fmt.Sprintf( - "Uptime: %.0fs\nConn total: %d\nConn bad: %d\nHandshake timeouts: %d\nUsers: %d", - s.UptimeSeconds, s.ConnectionsTotal, s.ConnectionsBadTotal, s.HandshakeTimeoutsTotal, s.ConfiguredUsers, - ) - return b.editMessageText(ctx, chatID, msgID, msg, backKeyboard()) + text := buildSummaryMessageHTML(s) + return b.editMessageTextHTML(ctx, chatID, msgID, text, backKeyboard(), true) } func (b *bot) handleUsersCB(ctx context.Context, chatID, msgID int64) error { @@ -741,6 +735,65 @@ func escapeHTML(s string) string { return s } +func yesNoRu(v bool) string { + if v { + return "да" + } + return "нет" +} + +// formatUptimeRu преобразует аптайм в секундах в читаемую строку на русском. +func formatUptimeRu(seconds float64) string { + if seconds < 0 { + seconds = 0 + } + s := int64(seconds + 0.5) + const day = 86400 + const hour = 3600 + const min = 60 + d := s / day + s %= day + h := s / hour + s %= hour + m := s / min + sec := s % min + + var parts []string + if d > 0 { + parts = append(parts, fmt.Sprintf("%d д.", d)) + } + if h > 0 || d > 0 { + parts = append(parts, fmt.Sprintf("%d ч.", h)) + } + if m > 0 || h > 0 || d > 0 { + parts = append(parts, fmt.Sprintf("%d мин.", m)) + } + parts = append(parts, fmt.Sprintf("%d с", sec)) + return strings.Join(parts, " ") +} + +func buildHealthMessageHTML(h healthData) string { + var sb strings.Builder + sb.WriteString("Состояние сервера\n") + sb.WriteString("проверка доступности и режима работы\n\n") + sb.WriteString(fmt.Sprintf("Статус: %s\n", escapeHTML(strings.TrimSpace(h.Status)))) + sb.WriteString(fmt.Sprintf("Только чтение: %s", yesNoRu(h.ReadOnly))) + return sb.String() +} + +func buildSummaryMessageHTML(s summaryData) string { + var sb strings.Builder + sb.WriteString("Сводка\n") + sb.WriteString("агрегированная статистика\n\n") + sb.WriteString(fmt.Sprintf("Время работы: %s\n", escapeHTML(formatUptimeRu(s.UptimeSeconds)))) + sb.WriteString(fmt.Sprintf(" (%.0f с)\n\n", s.UptimeSeconds)) + sb.WriteString(fmt.Sprintf("Всего соединений: %d\n", s.ConnectionsTotal)) + sb.WriteString(fmt.Sprintf("Сбойных соединений: %d\n", s.ConnectionsBadTotal)) + sb.WriteString(fmt.Sprintf("Таймауты рукопожатия: %d\n", s.HandshakeTimeoutsTotal)) + sb.WriteString(fmt.Sprintf("Пользователей в конфигурации: %d", s.ConfiguredUsers)) + return sb.String() +} + // formatTrafficRu форматирует объём в октетах (байтах) в удобочитаемый вид (двоичные приставки). func formatTrafficRu(octets uint64) string { if octets == 0 {