我在Powershell 3.0中编写了一个脚本来监视日志文件中的特定错误。该脚本启动后台进程,该进程监视该文件。当任何内容写入文件时,后台进程只是将其传递给前台进程,如果它匹配正确的格式(带日期戳的行)。然后,前台进程会计算错误数。
一切正常,没有错误。问题是,随着源日志文件大小的增加,Powershell消耗的内存会急剧增加。这些日志在旋转之前被限制在~24M,这相当于~250K线。在我的测试中,当日志大小达到约80K行左右时,监视器进程消耗250M RAM(前景和后台进程合并。当他们第一次启动时,他们消耗了大约70M。这种类型的增长是不可接受的我的环境。我能做些什么来减少这种情况?
这是脚本:
# Constants.
$F_IN = "C:\Temp\test.log"
$RE = "^\d+-\d+-\d+ \d+:\d+:\d+,.+ERROR.+Foo$"
$MAX_RESTARTS = 3 # Max restarts for failed background job.
$SLEEP_DELAY = 60 # In seconds.
# Background job.
$SCRIPT_BLOCK = { param($f, $r)
Get-Content -Path $f -Tail 0 -Wait -EA SilentlyContinue `
| Where { $_ -match $r }
}
function Start-FileMonitor {
Param([parameter(Mandatory=$true,Position=0)][alias("f")]
[String]$file,
[parameter(Mandatory=$true,Position=1)][alias("b")]
[ScriptBlock]$SCRIPT_BLOCK,
[parameter(Mandatory=$true,Position=2)][alias("re","r")]
[String]$regex)
$j = Start-Job -ScriptBlock $SCRIPT_BLOCK -Arg $file,$regex
return $j
}
function main {
# Tail log file in the background, return any errors.
$job = Start-FileMonitor -b $SCRIPT_BLOCK -f $F_IN -r $RE
$restarts = 0 # Current number of restarts.
# Poll background $job every $SLEEP_DELAY seconds.
While ($true) {
$a = (Receive-Job $job | Measure-Object)
If ($job.JobStateInfo.State -eq "Running") {
$restarts = 0
If ($a.Count -gt 0) {
$t0 = $a.Count
Write-Host "Error Count: ${t0}"
}
}
Else {
If ($restarts -lt $MAX_RESTARTS) {
$job = Start-FileMonitor -b $SCRIPT_BLOCK -f $F_IN -r $RE
$restarts++
Write-Host "Background job not running. Attempted restart ${restarts}."
}
Else {
Write-Host "`$MAX_RESTARTS (${MAX_RESTARTS}) exceeded. Exiting."
Break
}
}
# Sleep for $SLEEP_DELAY.
Start-Sleep -Seconds $SLEEP_DELAY
}
Write-Host "Done."
}
# Execute script.
main
......这是样本数据:
2015-11-19 00:00:00, WARN Foo
2015-11-19 00:00:00, ERROR Foo
为了复制这个问题:
C:\Temp\test.log
中。保存。Error Count:
行确认一切正常。powershell.exe
的内存消耗。注意它在400线增加了多少...... 800线...... 8,000线...... 80,000线......