5

これまでのところ、フォーラムで解決策や支援を見つけられないという要件があります...

問題:リアルタイムシステムを監視すると、これらは毎日ロールオーバーする非常に大きなログファイルを多数生成します。1GBは珍しいことではありません。私が行うことは、既知のエラー状態についてログ(末尾)を調べることです。または、監視したいその他の文字列。アクションを実行する必要がある場合があります。

この種の作業は時間と手間がかかり、人為的エラーがログ内の問題を見逃しやすいため、私はこのログファイルの監視を自動化しています。Servers Aliveという製品を使用してスケジュールされたチェックを実行し、ログファイルを監視して、サービスの問題を示している可能性のあるログエントリの発生を監視します。必要に応じて、他のスクリプトを呼び出してサービスを再起動できます。発生した問題を解決するため。

私は以前にPerlを使用してこれらのログ監視タスクのスクリプトを作成しましたが、これらのスクリプトは非常に高速ですが、必ずしもこれを行うための最もクリーンな方法ではありません。私はプログラマーではなく管理者であるため、開発者の方法論や経験がありません。に頼る。

以下のPerlコードスニペットは、ログファイルを「開いて」、ファイル$logfileの最後から特定の量のデータを「シーク」して、この時点からファイルの最後までデータを検索することを示しています。監視したいログエントリ。この例では、ログエントリは「No packet received from EISEC Client」です。

この例では、監視しているログエントリは、EISECサービスの問題を示しており、サービスを再起動するだけで通常は問題が解決します。これらはすべて、スケジュールされたチェックおよびアラートメカニズムとしてServersAliveを自動的に利用します。

Perlスクリプト関数

sub checkEisecSrvloggedon {

print "$logfile\n";

if (open (EISECSRV_LOGGEDON, $logfile)) {

    seek (EISECSRV_LOGGEDON, -40000, 2);

    $line = <EISECSRV_LOGGEDON>;

    $eisecsrvloggedon_ok = 0;

    while ($line = <EISECSRV_LOGGEDON>) {   

            if ($line =~/No packet received from EISEC Client/) {

                #increment counter
                ++$eisecsrvloggedon_ok; 

                }

            }
        }
    }

Windows Server 2008R2およびWindows7クライアントに移行したので、可能であればPowerShellを使用してこのソリューションを実装したいと思いますが、これを効率的に、迅速に、大きなメモリオーバーヘッドなしで実行する方法の詳細がわかりません。

Get-Contentベースのソリューションを試しましたが、ログファイル全体を読み取る必要があるため、ログファイルのクエリに時間がかかりすぎるため、これらのタイプのソリューションは使用できなくなります。場合によっては数分に1回、非常に定期的にこれらの大きなログファイルの数をチェックできるようにする必要があります。ログファイルの末尾をテーリングするのに最適なテールタイプのソリューションを見てきましたが、これらのスクリプトはSystem.IO.Fileメソッドを使用しています。これにより、スクリプトで達成したいパフォーマンス/速度が得られますが、PowerShellに精通していないため、この方法を使用して大きなログファイルの最後にすばやく到達し、所定の量のデータを入力してから、このログセクションで関連する文字列を検索します。

誰かアイデアはありますか?

4

3 に答える 3

6

PowerShell 3.0以降を使用している場合は、コマンドレットget-contentselect-stringコマンドレットを組み合わせて使用​​すると、同じ機能を利用できます。バージョン3.0以降、効率的な方法でファイルの最後のn行のみを返すオプションをget-contentサポートします。これを使用して、上記のPerlスクリプトを次のように再実装できます(最後の1000行を検索)。-tail

# Returns the number of occurrences
(get-content logfile.txt -Tail 1000 | select-string -pattern "No packet received from EISEC Client").Length
于 2012-11-29T11:40:19.707 に答える
2

逆に探すと、Poshcodeリポジトリへのこの貢献は、要件によく一致しているように見えます。

# Name: Get-Tail.ps1
# Author: William Stacey
# Created: 02/22/2007
# Description: Gets the last N lines of a file. Does scan from end-of-file so works on large files. Also has a loop flag that prompts for refresh.

function Get-Tail([string]$path = $(throw "Path name must be specified."), [int]$count = 10, [bool]$loop = $false)
{
    if ( $count -lt 1 ) {$(throw "Count must be greater than 1.")}
    function get-last
    {
        $lineCount = 0
        $reader = new-object -typename System.IO.StreamReader -argumentlist $path, $true
        [long]$pos = $reader.BaseStream.Length - 1

        while($pos -gt 0)
        {
            $reader.BaseStream.Position = $pos
            if ($reader.BaseStream.ReadByte() -eq 10)
            {
                if($pos -eq $reader.BaseStream.Length - 1)
                {
                    $count++
                }
                $lineCount++
                if ($lineCount -ge $count) { break }
            }
            $pos--
        } 

        if ($lineCount -lt $count)
        {
            $reader.BaseStream.Position = 0
        }

        while($line = $reader.ReadLine())
        {
            $lines += ,$line
        }

        $reader.Close()
        $lines
    }

    while(1)
    {
        get-last
        if ( ! $loop ) { break }
        $in = read-host -prompt "Hit [Enter] to tail again or Ctrl-C to exit"
    }
}
于 2012-11-29T11:46:34.757 に答える
1

PSCXGet-FileTailには、ファイルの最後の行を効率的に取得するという名前のコマンドレットがあり、ファイル全体を事前に読み取る必要がありません。

于 2012-11-29T11:39:33.023 に答える