fix: daily report без локального Telegram при fallback SAC (2.1.9-SAC)
Аналог ssh-monitor: report.daily.* только SAC/spool, timeout 45s, spool flush приоритет отчётам (50 файлов/цикл). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+5
-3
@@ -90,7 +90,7 @@ $script:SkipLogDetailLimit = 15
|
|||||||
# строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах).
|
# строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах).
|
||||||
# Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только
|
# Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только
|
||||||
# исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1).
|
# исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1).
|
||||||
$ScriptVersion = "2.1.8-SAC"
|
$ScriptVersion = "2.1.9-SAC"
|
||||||
|
|
||||||
# Логи (все под InstallRoot)
|
# Логи (все под InstallRoot)
|
||||||
$LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log"
|
$LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log"
|
||||||
@@ -258,7 +258,9 @@ $SacUrl = ''
|
|||||||
$SacApiKey = ''
|
$SacApiKey = ''
|
||||||
$SacSpoolDir = ''
|
$SacSpoolDir = ''
|
||||||
$SacAgentIdFile = ''
|
$SacAgentIdFile = ''
|
||||||
$SacTimeoutSec = 12
|
$SacTimeoutSec = 45
|
||||||
|
$SacSpoolFlushMaxFiles = 50
|
||||||
|
$SacSpoolMaxAgeHours = 72
|
||||||
$SacTlsSkipVerify = $false
|
$SacTlsSkipVerify = $false
|
||||||
$SacFallbackFailures = 5
|
$SacFallbackFailures = 5
|
||||||
|
|
||||||
@@ -5040,7 +5042,7 @@ function Start-LoginMonitor {
|
|||||||
$nextReportCheck = Check-AndSendDailyReport
|
$nextReportCheck = Check-AndSendDailyReport
|
||||||
}
|
}
|
||||||
if ($script:SacClientLoaded) {
|
if ($script:SacClientLoaded) {
|
||||||
Invoke-SacFlushSpool -MaxFiles 20 | Out-Null
|
Invoke-SacFlushSpool | Out-Null
|
||||||
if ((Get-SacNormalizedMode) -ne 'off' -and $now -ge $script:NextSacCommandPollTime) {
|
if ((Get-SacNormalizedMode) -ne 'off' -and $now -ge $script:NextSacCommandPollTime) {
|
||||||
Invoke-SacProcessPendingCommands | Out-Null
|
Invoke-SacProcessPendingCommands | Out-Null
|
||||||
$script:NextSacCommandPollTime = $now.AddSeconds($SacCommandPollIntervalSec)
|
$script:NextSacCommandPollTime = $now.AddSeconds($SacCommandPollIntervalSec)
|
||||||
|
|||||||
+75
-11
@@ -430,7 +430,7 @@ function Test-SacHealth {
|
|||||||
$base = Get-SacBaseUrl
|
$base = Get-SacBaseUrl
|
||||||
if ([string]::IsNullOrWhiteSpace($base)) { return $false }
|
if ([string]::IsNullOrWhiteSpace($base)) { return $false }
|
||||||
|
|
||||||
$timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 }
|
$timeout = Get-SacTimeoutSecResolved
|
||||||
try {
|
try {
|
||||||
Invoke-SacTlsPrep
|
Invoke-SacTlsPrep
|
||||||
$resp = Invoke-WebRequest -Uri "$base/health" -Method Get -UseBasicParsing -TimeoutSec $timeout
|
$resp = Invoke-WebRequest -Uri "$base/health" -Method Get -UseBasicParsing -TimeoutSec $timeout
|
||||||
@@ -691,7 +691,7 @@ function Invoke-SacPostPayload {
|
|||||||
if ($jsonText -match '"type"\s*:\s*"([^"]+)"') {
|
if ($jsonText -match '"type"\s*:\s*"([^"]+)"') {
|
||||||
$eventType = $Matches[1]
|
$eventType = $Matches[1]
|
||||||
}
|
}
|
||||||
$timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 }
|
$timeout = Get-SacTimeoutSecResolved
|
||||||
$spoolOnFailure = $true
|
$spoolOnFailure = $true
|
||||||
$bodyBytes = $null
|
$bodyBytes = $null
|
||||||
|
|
||||||
@@ -811,6 +811,31 @@ function Test-SacHeartbeatOnlyEventType {
|
|||||||
return ($EventType -eq 'agent.heartbeat')
|
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 {
|
function Merge-SacNotifyDetails {
|
||||||
param(
|
param(
|
||||||
[hashtable]$Details = $null,
|
[hashtable]$Details = $null,
|
||||||
@@ -883,6 +908,20 @@ function Send-NotifyOrSac {
|
|||||||
return (Send-SacEvent @sacEventArgs)
|
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) {
|
switch ($mode) {
|
||||||
'off' {
|
'off' {
|
||||||
return (Send-SacLocalChannels -TelegramMessage $TelegramMessage -EmailSubject $EmailSubject)
|
return (Send-SacLocalChannels -TelegramMessage $TelegramMessage -EmailSubject $EmailSubject)
|
||||||
@@ -914,7 +953,11 @@ function Send-NotifyOrSac {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Invoke-SacFlushSpool {
|
function Invoke-SacFlushSpool {
|
||||||
param([int]$MaxFiles = 20)
|
param([int]$MaxFiles = 0)
|
||||||
|
|
||||||
|
if ($MaxFiles -le 0) {
|
||||||
|
$MaxFiles = Get-SacSpoolFlushMaxFilesResolved
|
||||||
|
}
|
||||||
|
|
||||||
$mode = Get-SacNormalizedMode
|
$mode = Get-SacNormalizedMode
|
||||||
if ($mode -eq 'off') { return }
|
if ($mode -eq 'off') { return }
|
||||||
@@ -923,11 +966,32 @@ function Invoke-SacFlushSpool {
|
|||||||
$dir = Get-SacSpoolDirResolved
|
$dir = Get-SacSpoolDirResolved
|
||||||
if (-not (Test-Path -LiteralPath $dir)) { return }
|
if (-not (Test-Path -LiteralPath $dir)) { return }
|
||||||
|
|
||||||
# Сначала свежие события (daily report); битые записи уходят в rejected и не блокируют очередь.
|
$files = @(Get-ChildItem -LiteralPath $dir -Filter '*.json' -File -ErrorAction SilentlyContinue)
|
||||||
$files = @(Get-ChildItem -LiteralPath $dir -Filter '*.json' -File -ErrorAction SilentlyContinue |
|
$daily = @()
|
||||||
Sort-Object LastWriteTime -Descending)
|
$other = @()
|
||||||
$count = 0
|
|
||||||
foreach ($f in $files) {
|
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++
|
$count++
|
||||||
if ($count -gt $MaxFiles) { break }
|
if ($count -gt $MaxFiles) { break }
|
||||||
try {
|
try {
|
||||||
@@ -964,7 +1028,7 @@ function Get-SacAgentCommandResultUrl {
|
|||||||
function Invoke-SacHttpGet {
|
function Invoke-SacHttpGet {
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory = $true)][string]$Uri,
|
[Parameter(Mandatory = $true)][string]$Uri,
|
||||||
[int]$TimeoutSec = 12
|
[int]$TimeoutSec = 45
|
||||||
)
|
)
|
||||||
Invoke-SacTlsPrep
|
Invoke-SacTlsPrep
|
||||||
try {
|
try {
|
||||||
@@ -990,7 +1054,7 @@ function Invoke-SacHttpPostJson {
|
|||||||
param(
|
param(
|
||||||
[Parameter(Mandatory = $true)][string]$Uri,
|
[Parameter(Mandatory = $true)][string]$Uri,
|
||||||
[Parameter(Mandatory = $true)][string]$JsonBody,
|
[Parameter(Mandatory = $true)][string]$JsonBody,
|
||||||
[int]$TimeoutSec = 12
|
[int]$TimeoutSec = 45
|
||||||
)
|
)
|
||||||
Invoke-SacTlsPrep
|
Invoke-SacTlsPrep
|
||||||
$bytes = Get-SacUtf8Bytes -Text $JsonBody
|
$bytes = Get-SacUtf8Bytes -Text $JsonBody
|
||||||
@@ -1119,7 +1183,7 @@ function Submit-SacAgentCommandResult {
|
|||||||
stdout = $Stdout
|
stdout = $Stdout
|
||||||
stderr = $Stderr
|
stderr = $Stderr
|
||||||
} | ConvertTo-Json -Compress
|
} | ConvertTo-Json -Compress
|
||||||
$timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 }
|
$timeout = Get-SacTimeoutSecResolved
|
||||||
$resp = Invoke-SacHttpPostJson -Uri $url -JsonBody $body -TimeoutSec $timeout
|
$resp = Invoke-SacHttpPostJson -Uri $url -JsonBody $body -TimeoutSec $timeout
|
||||||
return ($resp.StatusCode -in 200, 201)
|
return ($resp.StatusCode -in 200, 201)
|
||||||
}
|
}
|
||||||
@@ -1132,7 +1196,7 @@ function Invoke-SacProcessPendingCommands {
|
|||||||
if ([string]::IsNullOrWhiteSpace($pollUrl)) { return 0 }
|
if ([string]::IsNullOrWhiteSpace($pollUrl)) { return 0 }
|
||||||
|
|
||||||
$agentId = Get-SacAgentInstanceId
|
$agentId = Get-SacAgentInstanceId
|
||||||
$timeout = if ($SacTimeoutSec) { [int]$SacTimeoutSec } else { 12 }
|
$timeout = Get-SacTimeoutSecResolved
|
||||||
$uri = "${pollUrl}?agent_instance_id=$([uri]::EscapeDataString($agentId))"
|
$uri = "${pollUrl}?agent_instance_id=$([uri]::EscapeDataString($agentId))"
|
||||||
$get = Invoke-SacHttpGet -Uri $uri -TimeoutSec $timeout
|
$get = Invoke-SacHttpGet -Uri $uri -TimeoutSec $timeout
|
||||||
if ($get.StatusCode -ne 200) {
|
if ($get.StatusCode -ne 200) {
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ $UseSAC = 'fallback'
|
|||||||
$SacUrl = 'https://sac.kalinamall.ru'
|
$SacUrl = 'https://sac.kalinamall.ru'
|
||||||
$SacApiKey = 'sac_UkOsAT3UWiQS54KK5OJPBDCSucysQDrKFju28wmYiz8'
|
$SacApiKey = 'sac_UkOsAT3UWiQS54KK5OJPBDCSucysQDrKFju28wmYiz8'
|
||||||
$SacSpoolDir = 'C:\ProgramData\RDP-login-monitor\sac-spool'
|
$SacSpoolDir = 'C:\ProgramData\RDP-login-monitor\sac-spool'
|
||||||
# $SacTimeoutSec = 12
|
$SacTimeoutSec = 45
|
||||||
|
$SacSpoolFlushMaxFiles = 50
|
||||||
|
$SacSpoolMaxAgeHours = 72
|
||||||
# $SacTlsSkipVerify = $false
|
# $SacTlsSkipVerify = $false
|
||||||
# $SacFallbackFailures = 5
|
# $SacFallbackFailures = 5
|
||||||
# $false = не слать report.daily.rdp с агента (суточный отчёт только из SAC)
|
# $false = не слать report.daily.rdp с агента (суточный отчёт только из SAC)
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
2.1.8-SAC
|
2.1.9-SAC
|
||||||
|
|||||||
Reference in New Issue
Block a user