diff --git a/Login_Monitor.ps1 b/Login_Monitor.ps1 index 3734b24..bc55350 100644 --- a/Login_Monitor.ps1 +++ b/Login_Monitor.ps1 @@ -90,7 +90,7 @@ $script:SkipLogDetailLimit = 15 # строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах). # Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только # исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1). -$ScriptVersion = "2.1.8-SAC" +$ScriptVersion = "2.1.9-SAC" # Логи (все под InstallRoot) $LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log" @@ -258,7 +258,9 @@ $SacUrl = '' $SacApiKey = '' $SacSpoolDir = '' $SacAgentIdFile = '' -$SacTimeoutSec = 12 +$SacTimeoutSec = 45 +$SacSpoolFlushMaxFiles = 50 +$SacSpoolMaxAgeHours = 72 $SacTlsSkipVerify = $false $SacFallbackFailures = 5 @@ -5040,7 +5042,7 @@ function Start-LoginMonitor { $nextReportCheck = Check-AndSendDailyReport } if ($script:SacClientLoaded) { - Invoke-SacFlushSpool -MaxFiles 20 | Out-Null + Invoke-SacFlushSpool | Out-Null if ((Get-SacNormalizedMode) -ne 'off' -and $now -ge $script:NextSacCommandPollTime) { Invoke-SacProcessPendingCommands | Out-Null $script:NextSacCommandPollTime = $now.AddSeconds($SacCommandPollIntervalSec) diff --git a/Sac-Client.ps1 b/Sac-Client.ps1 index ff6ddd3..54df8e1 100644 --- a/Sac-Client.ps1 +++ b/Sac-Client.ps1 @@ -430,7 +430,7 @@ function Test-SacHealth { $base = Get-SacBaseUrl if ([string]::IsNullOrWhiteSpace($base)) { return $false } - $timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 } + $timeout = Get-SacTimeoutSecResolved try { Invoke-SacTlsPrep $resp = Invoke-WebRequest -Uri "$base/health" -Method Get -UseBasicParsing -TimeoutSec $timeout @@ -691,7 +691,7 @@ function Invoke-SacPostPayload { if ($jsonText -match '"type"\s*:\s*"([^"]+)"') { $eventType = $Matches[1] } - $timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 } + $timeout = Get-SacTimeoutSecResolved $spoolOnFailure = $true $bodyBytes = $null @@ -811,6 +811,31 @@ function Test-SacHeartbeatOnlyEventType { return ($EventType -eq 'agent.heartbeat') } +function Test-SacDailyReportEventType { + param([string]$EventType) + return ($EventType -in @('report.daily.rdp', 'report.daily.ssh')) +} + +function Get-SacTimeoutSecResolved { + if ($SacTimeoutSec) { + $n = 0 + if ([int]::TryParse([string]$SacTimeoutSec, [ref]$n) -and $n -gt 0) { + return $n + } + } + return 45 +} + +function Get-SacSpoolFlushMaxFilesResolved { + if (Get-Variable -Name SacSpoolFlushMaxFiles -ErrorAction SilentlyContinue) { + $n = 0 + if ([int]::TryParse([string]$SacSpoolFlushMaxFiles, [ref]$n) -and $n -gt 0) { + return $n + } + } + return 50 +} + function Merge-SacNotifyDetails { param( [hashtable]$Details = $null, @@ -883,6 +908,20 @@ function Send-NotifyOrSac { return (Send-SacEvent @sacEventArgs) } + # Суточный отчёт — только SAC/spool; при сбое ingest не дублировать в локальный Telegram. + if (Test-SacDailyReportEventType -EventType $EventType) { + if ($mode -eq 'off') { + return $false + } + $merged = Merge-SacNotifyDetails -Details $Details -TelegramVia 'sac' + $sacEventArgs = Get-SacEventInvokeArgs -EventType $EventType -Severity $Severity -Title $Title -Summary $Summary -Details $merged -OccurredAt $OccurredAt + if (Send-SacEvent @sacEventArgs) { + return $true + } + Write-SacLog 'WARN: daily report не принят SAC — остаётся в spool (локальный Telegram пропущен)' + return $false + } + switch ($mode) { 'off' { return (Send-SacLocalChannels -TelegramMessage $TelegramMessage -EmailSubject $EmailSubject) @@ -914,7 +953,11 @@ function Send-NotifyOrSac { } function Invoke-SacFlushSpool { - param([int]$MaxFiles = 20) + param([int]$MaxFiles = 0) + + if ($MaxFiles -le 0) { + $MaxFiles = Get-SacSpoolFlushMaxFilesResolved + } $mode = Get-SacNormalizedMode if ($mode -eq 'off') { return } @@ -923,11 +966,32 @@ function Invoke-SacFlushSpool { $dir = Get-SacSpoolDirResolved if (-not (Test-Path -LiteralPath $dir)) { return } - # Сначала свежие события (daily report); битые записи уходят в rejected и не блокируют очередь. - $files = @(Get-ChildItem -LiteralPath $dir -Filter '*.json' -File -ErrorAction SilentlyContinue | - Sort-Object LastWriteTime -Descending) - $count = 0 + $files = @(Get-ChildItem -LiteralPath $dir -Filter '*.json' -File -ErrorAction SilentlyContinue) + $daily = @() + $other = @() foreach ($f in $files) { + $eventType = '' + try { + $raw = Read-SacSpoolFileText -Path $f.FullName + if (-not [string]::IsNullOrWhiteSpace($raw)) { + $obj = $raw | ConvertFrom-Json -ErrorAction Stop + if ($null -ne $obj.type) { $eventType = [string]$obj.type } + } + } catch { + $eventType = '' + } + if (Test-SacDailyReportEventType -EventType $eventType) { + $daily += $f + } else { + $other += $f + } + } + $ordered = @( + @($daily | Sort-Object LastWriteTime) + @($other | Sort-Object LastWriteTime) + ) + $count = 0 + foreach ($f in $ordered) { $count++ if ($count -gt $MaxFiles) { break } try { @@ -964,7 +1028,7 @@ function Get-SacAgentCommandResultUrl { function Invoke-SacHttpGet { param( [Parameter(Mandatory = $true)][string]$Uri, - [int]$TimeoutSec = 12 + [int]$TimeoutSec = 45 ) Invoke-SacTlsPrep try { @@ -990,7 +1054,7 @@ function Invoke-SacHttpPostJson { param( [Parameter(Mandatory = $true)][string]$Uri, [Parameter(Mandatory = $true)][string]$JsonBody, - [int]$TimeoutSec = 12 + [int]$TimeoutSec = 45 ) Invoke-SacTlsPrep $bytes = Get-SacUtf8Bytes -Text $JsonBody @@ -1119,7 +1183,7 @@ function Submit-SacAgentCommandResult { stdout = $Stdout stderr = $Stderr } | ConvertTo-Json -Compress - $timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 } + $timeout = Get-SacTimeoutSecResolved $resp = Invoke-SacHttpPostJson -Uri $url -JsonBody $body -TimeoutSec $timeout return ($resp.StatusCode -in 200, 201) } @@ -1132,7 +1196,7 @@ function Invoke-SacProcessPendingCommands { if ([string]::IsNullOrWhiteSpace($pollUrl)) { return 0 } $agentId = Get-SacAgentInstanceId - $timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 } + $timeout = Get-SacTimeoutSecResolved $uri = "${pollUrl}?agent_instance_id=$([uri]::EscapeDataString($agentId))" $get = Invoke-SacHttpGet -Uri $uri -TimeoutSec $timeout if ($get.StatusCode -ne 200) { diff --git a/login_monitor.settings.example.ps1 b/login_monitor.settings.example.ps1 index de9dcbd..2988296 100644 --- a/login_monitor.settings.example.ps1 +++ b/login_monitor.settings.example.ps1 @@ -37,7 +37,9 @@ $UseSAC = 'fallback' $SacUrl = 'https://sac.kalinamall.ru' $SacApiKey = 'sac_UkOsAT3UWiQS54KK5OJPBDCSucysQDrKFju28wmYiz8' $SacSpoolDir = 'C:\ProgramData\RDP-login-monitor\sac-spool' -# $SacTimeoutSec = 12 +$SacTimeoutSec = 45 +$SacSpoolFlushMaxFiles = 50 +$SacSpoolMaxAgeHours = 72 # $SacTlsSkipVerify = $false # $SacFallbackFailures = 5 # $false = не слать report.daily.rdp с агента (суточный отчёт только из SAC) diff --git a/version.txt b/version.txt index d09524a..4f49bf9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.1.8-SAC +2.1.9-SAC