我们有 2 个 SMTP 门,它们可以输出.log
大约一周的数据的文本文件(通常大约 10-30MB 个弹出)。总的来说,两者的大小通常约为 1.2GB。
我有(2)只读共享设置到日志目录,并试图使用解析日志条目Select-String
(例如,说我想看看“bdole”的电子邮件是否进来。如果我只想在线获得点击数字,没那么糟糕。
但是,我想获得整个“日志条目”。我最初的研究表明我需要立即阅读整个日志的内容,然后针对它执行正则表达式。所以,这就是我正在做的,将近 200 个文件。
但是,我不认为 i/o 才是真正的问题。我正在生成约 200 个线程(每个文件一个)并限制为 20 个线程。最初的 20 个线程需要一些时间才能运行。我输入了一些调试代码并回到单线程;似乎简单地正则表达式一个 10-20MB 文件的内容需要很长时间。
我怀疑我编写的正则表达式在速度方面非常不足(如果我让它运行一夜,它就可以正常工作。)另外,网络 I/O 非常低(峰值为 0.6% 2Ggpbs 连接),而 CPU/RAM 非常高。
理想的日志条目如下所示:
---- SMTPRS log entry made at mm/dd/yyyy HH:mm:ss
Incoming SMTP call from x.x.x.x at HH:mm:ss.
<<< 220 mail.foo.com
>>> QUIT
<<< 221 mail.foo.com closing
Incoming SMTP call from x.x.x.x completed at HH:mm:ss.
唯一可靠的分隔符是开始----
(有时它会/不会以 a 结尾----
)
“日志条目”的内容可能非常多变,包括被阻止连接的通知等。
我正在使用的正则表达式
(?sm)----((?!----).*?)(log entry)((?!----).*?)(#USERINPUT#)((?!----).*?)----
where#USERINPUT#
被传递给脚本的内容所取代。
解析代码
使用获取文件路径列表后gci
if ( !(Test-Path $path) ) {
write-error "issue accessing $path"
} else {
try {
$buffer = [io.file]::ReadAllText($path)
}
catch {
$errArray += $path
$_
}
[string[]]$matchBuffer = @()
$matchBuffer += $entrySeperator
$matchBuffer += $_
$matchBuffer += $entrySeperator
$matchBuffer += $buffer | Select-String $regex -AllMatches |
% {$_.Matches} |
% {$_.Value; $entrySeperator}
if ($errArray) {
write-warning "There were errors, probably in accessing files. "
$errArray
}
$fileName = (gi $path).Name
sc -path $tmpDir\$fileName -value $matchBuffer
$matchBuffer | Out-String
我几乎想知道解析“命中”(例如第 21 行上的 XXXX.LOG)并从上下文向后重建日志条目是否会更快/更好。