Powershellスクリプトにてログローテーションを行う

Powershellスクリプトにてログローテーションを行う方法について。

1. 動作確認環境

2. やりたいこと

  • copytruncate方式でログローテーションを行いたい
  • 指定した保存期間を経過したログファイルを削除したい

3. 実装例

ログローテーションに際して色々と考慮点はあるが、今回は可能な限りシンプルに実装してみた。

処理を加えることで、特定サイズに達した場合にローテーション、などといった制御も可能。

(1) ログローテーション

引数に対象ログファイルパスを渡すと、ログファイルが存在し、かつサイズが0でない場合、copytruncate方式でローテーションを行う。*1ローテーション後のログファイル名には接尾語として".yyyyMMddHHmmss"(ローテーション日時)が付与される。

Function Rotate-Log([string]$log)
{
    $today = Get-Date
    if (Test-Path($log)) {
        $item = Get-Item $log
        if ($item.Length -ne 0) {
            $old = $log + "." + $today.ToString("yyyyMMddHHmmss")
            Copy-Item $log $old -Force
            $null | Out-File $log -Encoding default -Force
        } 
    }
}
(2) ログ削除

引数にログ保管先ディレクトリパスとログ保管日数を渡すと、保管日数を超過したログを削除する。

Function Delete-Log([string]$log_dir, [int]$saving_days)
{
    $today = Get-Date
    if (Test-Path($log_dir)) {
        $logs = Get-ChildItem $log_dir
        foreach ($log in $logs) {
            if ($log.lastWriteTime -lt $today.AddDays(-$saving_days)) {
                Remove-Item $log.FullName -Force
            }
        }
    }
}

*1:copytruncate方式の一般的な留意事項として、copy処理とtruncate処理の間に出力されたログは保存されないため、常時大量のログが書込まれるファイルに対しては適用しないようにする