From a74c8df8771714953bb9d99b08b94ad67f9bcd93 Mon Sep 17 00:00:00 2001 From: PTah Date: Sun, 31 May 2026 12:25:50 +1000 Subject: [PATCH] feat: lifecycle notifications with telegram_via and settings reload 1.2.30-SAC Co-authored-by: Cursor --- Login_Monitor.ps1 | 46 ++++++++++++++++++++++++++++++++++++---------- Sac-Client.ps1 | 44 ++++++++++++++++++++++++++++++++------------ version.txt | 2 +- 3 files changed, 69 insertions(+), 23 deletions(-) diff --git a/Login_Monitor.ps1 b/Login_Monitor.ps1 index 47f8b87..c3a542c 100644 --- a/Login_Monitor.ps1 +++ b/Login_Monitor.ps1 @@ -80,7 +80,7 @@ $script:MonitorLoopInitialized = $false # строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах). # Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только # исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1). -$ScriptVersion = "1.2.29-SAC" +$ScriptVersion = "1.2.30-SAC" # Логи (все под InstallRoot) $LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log" @@ -952,6 +952,23 @@ function Send-MonitorNotification { return $anyOk } +function Send-RdpMonitorLifecycleNotification { + param( + [Parameter(Mandatory = $true)][string]$Lifecycle, + [Parameter(Mandatory = $true)][string]$Trigger, + [Parameter(Mandatory = $true)][string]$TelegramHtmlMessage, + [Parameter(Mandatory = $true)][string]$SacSummary, + [string]$SacTitle = '', + [string]$SacSeverity = 'info', + [string]$EmailSubject = 'RDP Login Monitor' + ) + + $title = if (-not [string]::IsNullOrWhiteSpace($SacTitle)) { $SacTitle } else { "RDP login monitor: $Lifecycle" } + Send-MonitorNotification -Message $TelegramHtmlMessage -EmailSubject $EmailSubject ` + -SacEventType 'agent.lifecycle' -SacSeverity $SacSeverity -SacTitle $title -SacSummary $SacSummary ` + -SacDetails @{ lifecycle = $Lifecycle; trigger = $Trigger } | Out-Null +} + function Test-Administrator { $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) @@ -1806,8 +1823,10 @@ function Send-Heartbeat { $message = "✅ Мониторинг логинов ЗАПУЩЕН`r`n" $message += "🏷️ Версия скрипта: $(ConvertTo-TelegramHtml $ScriptVersion)" $upd = Get-DeployUpdateMarker + $lifecycleTrigger = 'boot' if ($upd.PendingStartupNotice -and $upd.Version -eq $ScriptVersion -and -not [string]::IsNullOrWhiteSpace($upd.UpdatedAt)) { $message += " (обновлён $(ConvertTo-TelegramHtml $upd.UpdatedAt))" + $lifecycleTrigger = 'deploy_recycle' Set-DeployUpdateMarkerPendingOff -Marker $upd } $message += "`r`n" @@ -1863,11 +1882,10 @@ function Send-Heartbeat { $message += " IP из IIS не заданы (ExchangeIisLogPath пуст)." } } - Send-MonitorNotification -Message $message -EmailSubject "RDP Login Monitor: запуск" ` - -SacEventType 'agent.lifecycle' -SacSeverity 'info' ` + Send-RdpMonitorLifecycleNotification -Lifecycle 'started' -Trigger $lifecycleTrigger ` + -TelegramHtmlMessage $message -EmailSubject 'RDP Login Monitor: запуск' ` -SacTitle 'RDP login monitor started' ` - -SacSummary "Мониторинг запущен на $(Get-MonitorServerLabel), версия $ScriptVersion" ` - -SacDetails @{ lifecycle = 'started' } | Out-Null + -SacSummary "Мониторинг запущен на $(Get-MonitorServerLabel), версия $ScriptVersion" Write-Log "Отправлено уведомление о запуске скрипта (каналы: $notifyChain)" } else { Write-TextFileUtf8Bom -Path $HeartbeatFile -Text $timestamp @@ -1944,11 +1962,10 @@ function Send-StopNotification { $message += "🕐 Время остановки: $timestamp`r`n" $message += "📋 Причина: $hReason" - Send-MonitorNotification -Message $message -EmailSubject "RDP Login Monitor: остановка" ` - -SacEventType 'agent.lifecycle' -SacSeverity 'info' ` - -SacTitle 'RDP login monitor stopped' ` - -SacSummary "Мониторинг остановлен: $Reason" ` - -SacDetails @{ lifecycle = 'stopped'; reason = $Reason } | Out-Null + Send-RdpMonitorLifecycleNotification -Lifecycle 'stopped' -Trigger 'shutdown' ` + -TelegramHtmlMessage $message -EmailSubject 'RDP Login Monitor: остановка' ` + -SacTitle 'RDP login monitor stopped' -SacSeverity 'info' ` + -SacSummary "Мониторинг остановлен: $Reason" Write-Log "Уведомление об остановке отправлено: $Reason" } @@ -3175,6 +3192,15 @@ function Start-LoginMonitor { } Write-Log "Graceful restart (settings): запрос '$($restartReq.Reason)' — перечитываю настройки в этом же процессе PowerShell." Invoke-RdpMonitorReloadSettings | Out-Null + $hHost = ConvertTo-TelegramHtml (Get-MonitorServerLabel) + $reloadMsg = "🔄 Настройки монитора перечитаны`r`n" + $reloadMsg += "🖥️ Сервер: $hHost`r`n" + $reloadMsg += "🏷️ Версия: $(ConvertTo-TelegramHtml $ScriptVersion)`r`n" + $reloadMsg += "📢 Каналы: $(ConvertTo-TelegramHtml (Get-NotifyChainHuman))" + Send-RdpMonitorLifecycleNotification -Lifecycle 'settings_reloaded' -Trigger 'settings_reload' ` + -TelegramHtmlMessage $reloadMsg -EmailSubject 'RDP Login Monitor: settings reload' ` + -SacTitle 'RDP login monitor settings reloaded' ` + -SacSummary "Настройки перечитаны на $(Get-MonitorServerLabel), версия $ScriptVersion" break } diff --git a/Sac-Client.ps1 b/Sac-Client.ps1 index ffd52bf..c82c9fe 100644 --- a/Sac-Client.ps1 +++ b/Sac-Client.ps1 @@ -624,14 +624,9 @@ function Send-SacEvent { return $false } - $mergedDetails = @{} - if ($null -ne $Details) { - foreach ($k in $Details.Keys) { - $mergedDetails[$k] = $Details[$k] - } - } - if (-not $mergedDetails.ContainsKey('generated_by')) { - $mergedDetails['generated_by'] = 'agent' + $mergedDetails = Merge-SacNotifyDetails -Details $Details -TelegramVia '' + if ($mergedDetails.Count -eq 0) { + $mergedDetails = $null } $payload = $(New-SacEventPayload -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $mergedDetails) @@ -675,6 +670,27 @@ function Test-SacHeartbeatOnlyEventType { return ($EventType -eq 'agent.heartbeat') } +function Merge-SacNotifyDetails { + param( + [hashtable]$Details = $null, + [string]$TelegramVia = '' + ) + + $merged = @{} + if ($null -ne $Details) { + foreach ($k in $Details.Keys) { + $merged[$k] = $Details[$k] + } + } + if (-not $merged.ContainsKey('generated_by')) { + $merged['generated_by'] = 'agent' + } + if (-not [string]::IsNullOrWhiteSpace($TelegramVia) -and -not $merged.ContainsKey('telegram_via')) { + $merged['telegram_via'] = $TelegramVia.Trim().ToLowerInvariant() + } + return $merged +} + function Send-NotifyOrSac { param( [Parameter(Mandatory = $true)][string]$EventType, @@ -697,7 +713,8 @@ function Send-NotifyOrSac { if ($mode -eq 'off') { return $false } - return (Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $Details) + $hbDetails = Merge-SacNotifyDetails -Details $Details -TelegramVia 'sac' + return (Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $hbDetails) } switch ($mode) { @@ -705,14 +722,17 @@ function Send-NotifyOrSac { return (Send-SacLocalChannels -TelegramMessage $TelegramMessage -EmailSubject $EmailSubject) } 'exclusive' { - return (Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $Details) + $merged = Merge-SacNotifyDetails -Details $Details -TelegramVia 'sac' + return (Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $merged) } 'dual' { - Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $Details | Out-Null + $merged = Merge-SacNotifyDetails -Details $Details -TelegramVia 'agent' + Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $merged | Out-Null return (Send-SacLocalChannels -TelegramMessage $TelegramMessage -EmailSubject $EmailSubject) } 'fallback' { - if (Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $Details) { + $merged = Merge-SacNotifyDetails -Details $Details -TelegramVia 'sac' + if (Send-SacEvent -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $merged) { return $true } return (Send-SacLocalChannels -TelegramMessage $TelegramMessage -EmailSubject $EmailSubject) diff --git a/version.txt b/version.txt index 5f1de29..16f664c 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.2.29-SAC +1.2.30-SAC