2016-05-25 15 views
0

私の会社は特定のエラーをチェックするためにTomcatのログファイルを分析し、Powershellを使用する必要があります。これらのエラーは配列に格納され、1:1に対してチェックされます。これは、Windowsタスクスケジューラを使用して30分ごとに発生します。このようなエラーがログファイルに見つかった場合、生成されたテキストファイルが管理者に送信されます。定義された時間より長いログファイルのエントリを見つける

ただし、過去30分間の間にエラーをチェックするのはあまり重要ではありません。私はこのようなエラーの有無を確認する上でその後

$logTimeStart = (Get-Date).AddMinutes(-30).ToString("yyyy-MM-dd HH:mm:ss") 

は、だから私は初めてのための変数を定義している

$request = Get-Content ($logFile) | select -last 100 | where { $_ -match $errorName -and $_ -gt $logTimeStart } 

は、残念ながら、これは動作しません。この間隔の30分前に発生したエラーも送信します。ここで

は、Tomcatログの抜粋です:

2016-05-25 14:21:30,669 FATAL [http-apr-8080-exec-4] [email protected] de.abc.def.business.service.ExplorerService GH00000476: 
de.abc.def.business.VisjBusinessException: Invalid InstanceId 
    at de.abc.def.business.service.ExplorerService$ExplorerServiceStatic.getExplorer(ExplorerService.java:721) 
    at de.abc.def.business.service.ExplorerService$ExplorerServiceStatic.getTreeItemList(ExplorerService.java:823) 
    at sun.reflect.GeneratedMethodAccessor141.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at de.abc.def.business.provider.ServiceProvider.callServiceMethod(ServiceProvider.java:258) 
    at de.abc.def.business.communication.web.client.ServiceDirectWrapperDelegate.callServiceMethod(ServiceDirectWrapperDelegate.java:119) 
    at de.abc.def.business.communication.web.client.ServiceWrapperBase.callServiceMethod(ServiceWrapperBase.java:196) 
    at de.abc.def.business.communication.web.client.ServiceDirectWrapper.callServiceMethod(ServiceDirectWrapper.java:24) 
    at de.abc.def.web.app.service.stub.AbstractBaseStub.callServiceMethodDirect(AbstractBaseStub.java:72) 
    at de.abc.def.web.app.service.stub.AbstractBaseStub.callServiceMethod(AbstractBaseStub.java:183) 
    at de.abc.def.web.app.service.stub.StubSrvExplorer.getTreeItemList(StubSrvExplorer.java:135) 
    at de.abc.def.web.app.resource.servlet.ExplorerServlet.createXml(ExplorerServlet.java:350) 
    at de.abc.def.web.app.resource.servlet.ExplorerServlet.callExplorerServlet(ExplorerServlet.java:101) 
    at de.abc.def.web.app.resource.servlet.VisServlet.handleServlets(VisServlet.java:244) 
    at de.abc.def.web.app.FlowControlAction.isPing(FlowControlAction.java:148) 
    at de.abc.def.web.app.FlowControlAction.execute(FlowControlAction.java:101) 
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484) 
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)

残念ながら1は、このようなエラーの行が表示されますどのように多くの言うことができません。したがって、100は単なる推定値です(うまくいく)。

は、どのように正しいものに関連したライン

$request = Get-Content ($logFile) | select -last 100 | 
      where { $_ -match $errorName -and $_ -gt $logTimeStart } 

を変更するには?

+0

umangledログのサンプルをご提示ください。 –

+0

あなたの質問ごとに私のリクエストを編集しました。 – Joey

+0

私は言いました。元のテキストがどのように見えるかを見る必要があります(インデントとすべて)。行を分割したり結合したりせずに、ログファイルからコピー/ペーストします。挿入したスニペットを選択し、エディットボックスの上の '{}'シンボルをクリックします。 –

答えて

1

Select-Stringと正規表現を使用してログファイルを解析します。基本的に、ログエントリは、タイムスタンプ、重大度、およびメッセージ(複数の行にまたがることがあります)から構成されます。そのため、正規表現は次のようになります。

(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3})\s+(\w+)\s+(.*(?:\n\D.*)*(?:\n\t.*)*)

(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3})は、タイムスタンプと一致しました。
(\w+)は重大度と一致します。
(.*(?:\n\D.*)*)は、ログメッセージ(現在の行の後ろに数字で始まらない0行以上の行)が一致します。

各サブ式の周りのカッコは、カスタムオブジェクトのプロパティを設定するために使用できるグループとしてサブダッチを取得します。 (ISO形式の日付文字列をしても文字列の比較で適切にソートすることができますので)DateTime値に日付の部分文字列を解析

$datefmt = 'yyyy-MM-dd HH:mm:ss,FFF' 
$culture = [Globalization.CultureInfo]::InvariantCulture 
$pattern = '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3})\s+(\w+)\s+(.*(?:\r\n\D.*)*)' 
$file = 'C:\path\to\your.log' 

Get-Content $file -Raw | Select-String $pattern -AllMatches | ForEach-Object { 
    $_.Matches | ForEach-Object { 
    New-Object -Type PSObject -Property @{ 
     Timestamp = [DateTime]::ParseExact($_.Groups[1].Value, $datefmt, $culture) 
     Severity = $_.Groups[2].Value 
     Message = $_.Groups[3].Value 
    } 
    } 
} 

実際に必要とされていないが、それはあなたが変換する必要はありません持っていてうれしいです参照タイムスタンプを書式付き文字列に変換します。

これが機能するには、ログファイル全体を単一の文字列として読み取る必要があることに注意してください。 PowerShell v3以降では、パラメータ-Rawを使用してGet-Contentを呼び出してこれを実現できます。以前のバージョンでは、あなたは、パイプOut-StringコマンドレットによるGet-Contentの出力は、同じ結果を取得することができます。

Get-Content $file | Out-String | ... 
+0

それは印象的です(私は正直言って私が完全に理解していないと認めなければなりません)。しかし、 '$ file'に関連エントリを入力すると、次のように尋ねられます: _cmdlet ForEach-Objectコマンドパイプライン位置3 次のパラメータの値を入力してください: プロセス[0]:_ 今しなければならない? – Joey

+0

@Joey質問を現在のコードで更新してください。おそらくどこかでタイプミスがあります。 –

+0

もう一度私に戻ってくれてありがとう。 '$ file = 'D:\ Logs \ output.log' 'を変更したことを除いて、_y_行を以前に書いたものをすべて削除したので、_my_コードに関してはあまり提供しません。 – Joey

関連する問題