2025年1月9日木曜日

powershellで作るlog確認ツールの話

 そろそろvbsが非推奨になるとかなんとかがで、log確認ツールをpowershellで作った。もちろんpowershellである必要は無いのだが、powershellだとwindowsで標準なので特段の準備が不要なのはとても良い(powershell5.xに限る)…7だと標準じゃないので、それ使うならpythonなり使った方が融通が利いて便利そう…

ps1ファイルの実行には癖があるが、実行用batを作るのは一つの手ではないか。ps1ファイルと同じ場所に以下の実行用batを置いておくと、batをクリックして実行することができる。ps1のファイル名は適当なので適宜変更してほしい。
set _folder=%~dp0
powershell -ExecutionPolicy RemoteSigned -File %_folder%_logCheck.ps1

実際のプログラム本体は末尾に示すとしていくつか説明を。確認したいlogファイルを収めたフォルダに、本体のps1ファイルと検索したいワードを収めた"_logChrList.txt"の二つを格納する。_logChrList.txtの中身の例は以下の画像に示す。

powershell5ではtextファイルのエンコードを自動で正しく取れないので、実行時にファイルのエンコードをs/uで入力する。これはlogファイルごとに判定しているのではなく、フォルダ内の全てのlogのエンコードを一括で指定しているので、フォルダ内に複数のエンコードが混在していると文字化けしてしまう。

実行すると同じフォルダに_LogCheckResult.txtの名前でチェック結果が格納される。フォルダ内のすべてのlogファイル内に、_logChrList.txtで指定した文字列が何件含まれているかを出力する。この際ファイル毎/文字列毎に件数を出す。上記の画像の例だとerrorの件数とwarningの件数をそれぞれ数える。面倒だったので実行結果を固定名で出しているので、同じファイル名の実行結果があると問答無用で上書きされる。

繰り返すがチェックしたいlogが格納されているフォルダに、ps1ファイルの本体と、_logChrList.txtの二つを追加して実行、実行結果が同じフォルダに_LogCheckResult.txtが出力される。この時注意としては_logChrList.txtはutf8で作成し、_LogCheckResult.txtはutf8で出力される。

以下がps1ファイルの中身。


#エンコードを入力して指定

do {

    $input = Read-Host "logのエンコード方式を選択してください ('s' で shift-jis, 'u' で utf8)"

    switch ($input) {

        's' { $encode = 'default'; break }

        'u' { $encode = 'utf8'; break }

        default { Write-Host "無効な入力です。再度入力してください。" }

    }

} while ($input -ne 's' -and $input -ne 'u')


#本体の処理

$_inpath = $PSScriptRoot ;

$_list = Get-Content -Encoding utf8 "$_inpath\_logChrList.txt"


$_resFileName = "_LogCheckResult.txt"

New-Item -ItemType file -Path $_inpath\$_resFileName -Force 


Get-ChildItem -Path $_inpath -Filter *.log -Recurse | ForEach-Object {


    # logファイルの中身を取得 

    $_content = Get-Content -Encoding $encode $_.FullName 


    # ファイル名を出力

    Add-Content -Path $_inpath\$_resFileName -Value "$($_.FullName):" 


    $count = @{}

    foreach ($_msg in $_list) {

        

        $count[$_msg] = ($_content | Select-String -Pattern $_msg).count


        #該当箇所が0件でなかったら出力

        if ($($count[$_msg]) -ne 0) {

            Add-Content -Path $_inpath\$_resFileName -Value " $_msg : $($count[$_msg])" 

        }

    }


    # ファイルの区切りを判別するために空行を挿入

    Add-Content -Path $_inpath\$_resFileName -Value " "


}


#BOMアリのutf8をbom無しに変換する powershell5は標準出力がbomアリのutf8のため変換が必要

$_outfile = -join($_inpath,"\",$_resFileName)

$_chgnobom = Get-Content $_outfile

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)

[System.IO.File]::WriteAllLines($_outfile, $_chgnobom, $Utf8NoBomEncoding)


write-host "end"

0 件のコメント:

コメントを投稿