0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Powershell用のロギングクラス

Last updated at Posted at 2023-05-23

log4jを意識したインターフェースで作成しています。
使用方法などは実装コードのコメント、プロパティ、単体テストコードを参照いただけると幸いです。

実装

Logger.ps1
<#
.SYNOPSIS
指定されたフォーマットで指定されたディレクトリにログを書き込むためのLoggerクラス。

.DESCRIPTION
Loggerクラスは、各種レベル(デバッグ、情報、警告、エラー)でログを書き込むメソッドを提供します。ログは、logDirフィールドで指定されたディレクトリに、logLayoutフィールドで指定されたフォーマットで書き込まれます。

.PARAMETER encoding
ログファイルの文字エンコーディング。デフォルトは "Default"。

.PARAMETER logLayout
ログメッセージのレイアウト。デフォルトは "%d %s %p %m"。

.PARAMETER datetimeLayout
日時のフォーマット。デフォルトは "yyyyMMddTHHmmssZ"。

.METHOD debug
デバッグレベルのログを書き込みます。

.METHOD info
情報レベルのログを書き込みます。

.METHOD warn
警告レベルのログを書き込みます。

.METHOD error
エラーレベルのログを書き込みます。

.EXAMPLE
$logger = New-Object Logger($MyInvocation)
$logger.info("これは情報レベルのログメッセージです。")
$logger.error("これはエラーレベルのログメッセージです。")
#>

class Logger {
    # Properties(Required)
    [string] $encoding = "Default"
    [string] $logLayout = "%d %s %p %m"
    [string] $datetimeLayout = "yyyyMMddTHHmmssZ"

    # Properties(Auto-Configured)
    [string] $scriptName
    [string] $logCreatedDatetime
    [string] $logDir
    [string] $logFilename

    Logger ($InvokingScriptMyInvocation) {
        $this.scriptName = (Split-Path -Leaf $InvokingScriptMyInvocation.MyCommand.Name).replace(".ps1", "")
        $this.logCreatedDatetime = Get-Date -Format yyyyMMdd
        $this.logDir = (Split-Path -Parent $InvokingScriptMyInvocation.MyCommand.Path)
        $this.logFilename = (Split-Path -Leaf $InvokingScriptMyInvocation.MyCommand.Name).replace(".ps1", "-" + $this.logCreatedDatetime + ".log")
    }

    [void] debug($msg) {
        $this.writeLog($msg, "DEBUG")
    }

    [void] info($msg) {
        $this.writeLog($msg, "INFO")
    }

    [void] warn($msg) {
        $this.writeLog($msg, "WARN")
    }

    [void] error($msg) {
        $this.writeLog($msg, "ERROR")
    }

    [void] writeLog($msg, $logLevel) {

        $replacedLayout = $this.logLayout
        $replacedLayout = $replacedLayout.replace("%d", (Get-Date -Format $this.datetimeLayout))
        $replacedLayout = $replacedLayout.replace("%p", $logLevel)
        $replacedLayout = $replacedLayout.replace("%s", $this.scriptName)
        $replacedLayout = $replacedLayout.replace("%m", $msg)

        Write-Output $replacedLayout | Out-File -FilePath (Join-Path $this.logDir $this.logFilename) -Append -Encoding $this.encoding
    }
}

使用方法と簡単な単体テスト

Logger.Tests.ps1
# Needed "Install-Module -Name Pester -Force -SkipPublisherCheck"
# Load Logger script ( need to store the Logger.ps1 in the same directory )
. ($PSCommandPath.replace(".Tests", ""))

# $MyInvocation of this script cannot be obtained in the It section.
$testScriptMyInvocation = $MyInvocation

Describe "LoggerUnitTest" {
    
    It "Regular-TestCase" {

        $Logger = New-Object Logger($testScriptMyInvocation)
        $msg = "test-message"

        $Logger.debug($msg)
        Get-Content (Join-Path $Logger.logDir $Logger.logFilename) -Tail 1 | Should -Match ".*DEBUG.*$msg.*" 

        $Logger.info($msg)
        Get-Content (Join-Path $Logger.logDir $Logger.logFilename) -Tail 1 | Should -Match ".*INFO.*$msg.*" 

        $Logger.warn($msg)
        Get-Content (Join-Path $Logger.logDir $Logger.logFilename) -Tail 1 | Should -Match ".*WARN.*$msg.*" 

        $Logger.error($msg)
        Get-Content (Join-Path $Logger.logDir $Logger.logFilename) -Tail 1 | Should -Match ".*ERROR.*$msg.*" 

    }

    It "Exception-TestCase" {

        $Logger = New-Object Logger($testScriptMyInvocation)
        # Specific Non-Existing Directory
        $Logger.logDir = (Join-Path $Logger.logDir "DummyDummyDir")
        
        { $Logger.debug($msg) } | Should -Throw -ExceptionType System.IO.DirectoryNotFoundException

    }

}
同一ディレクトリに実装とテストスクリプトを格納し実行
PS c:\logger> (Invoke-Pester ./Logger.Tests.ps1 -CodeCoverage ./Logger.ps1 -PassThru).CodeCoverage
Logger.Tests-20230524.log (ログ出力結果)
20230524T153012Z Logger.Tests DEBUG test-message
20230524T153012Z Logger.Tests INFO test-message
20230524T153012Z Logger.Tests WARN test-message
20230524T153012Z Logger.Tests ERROR test-message
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?