39
34

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 5 years have passed since last update.

PowerShell でのログ出力を頑張っていたら logger オブジェクトができた

Last updated at Posted at 2016-07-17

経緯

この 2 ヶ月、仕事で結構 PowerShell でスクリプトを作っている。
毎回テキトーにログ出していたらログの使い勝手が悪いので、ログ出力をユーザー定義関数として作ったが、状態を持てないのでなんかダサかった。

# 理想
$logger.info("log message")
$logger.error("log message")

# 現実
Put-Log -Message "log message" -File "C:\hoge.txt" -Info 
Put-Log -Message "log message" -File "C:\hoge.txt" -ERROR 

ログファイルのパスをグローバル変数にするとか色々考えていたけど、ふと、「スクリプトブロックを使ったらなんか上手くいくんじゃね?」と思い、車輪の再発明になるのだろうが自作してみた。後悔はしていない。

Claas を使うという事も一瞬頭を過ぎったが、PowerShell 5.0 を仕事で使うのはまだ先になりそうなのですぐに使えるほうを選んだ。

結果(使用方法)

ログを画面出力する(Write-Host 使用)

# ロガーオブジェクト取得
$logger = Get-Logger

# ログレベル Info でログを出力
$logger.info.Invoke("Message")

# ログレベル Warninng でログを出力
$logger.warn.Invoke("Message")

# ログレベル Error でログを出力
$logger.error.Invoke("Message")

画面出力と同時にログファイルを出力

# ログファイルをセットしてロガーオブジェクトを取得
$logger = Get-Logger -Logfile "C:\hoge\hoge.log"

# ログレベル Info でログを出力
$logger.info.Invoke("Message")

画面出力は行わず、ログファイルのみ出力

# ログファイルをセットし、ディスプレイ出力を止めるスイッチを付けてロガーオブジェクトを取得
$logger = Get-Logger -Logfile "C:\hoge\hoge.log" -NoDisplay

# ログレベルを Info  でログを出力
$logger.info.Invoke("Message")

コード

function Global:Get-Logger{
    Param(
        [CmdletBinding()]
        [Parameter()]
        [String]$Delimiter = " ",
        [Parameter()]
        [String]$Logfile,
        [Parameter()]
        [String]$Encoding = "Default",
        [Parameter()]
        [Switch]$NoDisplay
    )
    if (!(Test-Path -LiteralPath (Split-Path $Logfile -parent) -PathType container)) {
        New-Item $Logfile -type file -Force
    }
    $logger = @{}
    $logger.Set_Item('info', (Put-Log -Delimiter $Delimiter -Logfile $logfile -Encoding $Encoding -NoDisplay $NoDisplay -Info))
    $logger.Set_Item('warn', (Put-Log -Delimiter $Delimiter -Logfile $logfile -Encoding $Encoding -NoDisplay $NoDisplay -Warn))
    $logger.Set_Item('error', (Put-Log -Delimiter $Delimiter -Logfile $logfile -Encoding $Encoding -NoDisplay $NoDisplay -Err))
    return $logger
}

function Global:Put-Log
{
    Param(
        [CmdletBinding()]
        [Parameter()]
        [String]$Delimiter = " ",
        [Parameter()]
        [String]$Logfile,
        [Parameter()]
        [String]$Encoding,
        [Parameter()]
        [bool]$NoDisplay,
        [Parameter()]
        [Switch]$Info,
        [Parameter()]
        [Switch]$Warn,
        [Parameter()]
        [Switch]$Err
    )
    return {
        param([String]$msg = "")

        # Initialize variables
        $logparam = @("White", "INFO")
        if ($Warn)  { $logparam = @("Yellow", "WARN") }
        if ($Err) { $logparam = @("Red", "ERROR") }
        $txt = "[$(Get-Date -Format "yyyy/MM/dd HH:mm:ss")]${Delimiter}{0}${Delimiter}{1}" -f $logparam[1], $msg

        # Output Display
        if(!$NoDisplay) {
            Write-Host -ForegroundColor $logparam[0] $txt
        }
        # Output logfile
        if($Logfile) {
            Write-Output $txt | Out-File -FilePath $Logfile -Append -Encoding $Encoding
        }
    }.GetNewClosure()
}

最新のコードは GitHub 参照。

考察

結構理想に近い結果になったし、PowerShell 触り始めて 2 ヶ月、PowerShell と少し仲良くなれた気がする。指摘があれば優しくお願いします!

PowerShell のバージョンを指定して、2.0 でも動いたし、割と使える気がしているので、まずは仕事で使ってみようかな。

参考

39
34
1

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
39
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?