.log
約 1 週間分のデータのテキスト ファイル (通常は 1 ポップあたり約 10 ~ 30 MB)を吐き出す 2 つの SMTP ゲートがあります。合計すると、通常、どちらも約 1.2 GB のサイズになります。
(2) ログ ディレクトリに読み取り専用の共有を設定し、ログ エントリを解析しようとしていますSelect-String
(たとえば、"bdole" からの電子メールが届いたかどうかを確認したいとします。数値、悪くないです。
ただし、「ログエントリ」全体を取得したい。私の最初の調査によると、ログの内容全体を一度に読み取り、それに対して正規表現を実行する必要があります。これが私がやっていることで、200 近くのファイルに対してです。
ただし、本当の問題は i/o ではないと思います。私は ~200 スレッド (ファイルごとに 1 つ) を生成し、20 スレッドで上限を設定しています。最初の 20 スレッドの実行には時間がかかります。デバッグ コードを挿入して、シングル スレッドに戻りました。10 ~ 20 MB のファイルの内容を単純に正規表現すると、長い時間がかかるようです。
私が書いた正規表現は速度の点でどういうわけか非常に不十分であると思われます (一晩実行させても問題なく動作するという意味で機能します)。さらに、ネットワーク 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.
信頼できる唯一の区切り文字は開始です----
(場合によっては、で終わる/終わらない----
)
「ログエントリ」の内容は、ブロックされた接続の通知など、非常に変化しやすい場合があります。
私が使用している正規表現
(?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
「ヒット」(LINE 21 の XXXX.LOG など) を解析し、逆方向に作業してコンテキストからログ エントリを再構築する方が高速で優れているのではないかと考えています。