2014-08-28 131 views
2

如果我有一個PowerShell腳本說叫caller.ps1它看起來像這樣相應的日誌記錄

.\Lib\library.ps1 

$output = SomeLibraryFunction 

其中library.ps1如下所示

function SomeLibraryFunction() 
{ 
    Write-Output "Some meaningful function logging text" 
    Write-Output "return value" 
} 

我想要實現的是庫函數可以返回它的值的方法,但也可以添加一些日誌消息,以便調用者按照他們認爲合適的方式處理這些內部消息。我能想到的最好的方法是將兩者寫入管道,然後調用者將擁有一個實際返回值加上內部消息的數組,這些消息可能對調用腳本具有的記錄器有用。

我是否正確地處理這個問題?有沒有更好的方法來實現這一目標?

+0

也許['三通Object'(http://technet.microsoft.com/en-us/library/hh849937.aspx)將使用 – Matt 2014-08-28 15:54:36

回答

4

將日誌消息與實際輸出混合通常不是一個好主意。您的功能的消費者必須進行大量過濾才能找到他們真正想要的對象。

您的函數應該將日誌消息寫入詳細的輸出流。如果來電者希望看到這些消息,則可以通過指定-Verbose切換到您的功能。

function SomeLibraryFunction() 
{ 
    [CmdletBinding()] 
    param(
    ) 

    Write-Verbose "Some meaningful function logging text" 
    Write-Output "return value" 
} 

在PowerShell中3+,消費者可以redirect your verbose messages to the output stream or a file

# Show verbose logging messages on the console 
SomeLibraryFunction -Verbose 

# Send verbose logging messages to a file 
SomeLibraryFunction -Verbose 4> verbose.txt 

# redirect verbose message to the output stream 
SomeLibraryFunction -Verbose 4>&1 

其他選項包括:

  • 寫一個衆所周知的文件
  • 寫入事件日誌
  • 使用Start-Transcript創建會話日誌。
+0

不錯,我知道Write-Verbose,但我不知道我可以從管道中將它從其他Write-Output值中過濾出來。乾杯 – user1054637 2014-08-29 09:00:46

1

喜歡的東西三通對象可能對你有幫助

function SomeLibraryFunction() 
{ 
    $filepath = "C:\temp\log.txt" 
    write-output "Some meaningful function logging text" | Tee-Object -FilePath $filepath -Append 
    write-output "return value" | Tee-Object -FilePath $filepath -Append 
} 

有關三通對象的詳細信息看here

你可以使用基於變量的If聲明像$logging=$true,但我可以看到那變得混亂。

另一種方法

如果你正在尋找更多的可選方案的話,也許你可以使用類似這樣Start-TranscriptStop-Transcript其在文本文件中創建一個Windows PowerShell會話的全部或部分的記錄。

function SomeLibraryFunction() 
{ 
    write-output "Some meaningful function logging text" 
    write-output "return value" 
} 


$logging = $True 
If ($logging){ 
    Start-Transcript -Path C:\temp\log.txt -Append 
} 

SomeLibraryFunction 

If ($logging){ 
    Stop-Transcript 
} 

這只是表明您可以切換開始和停止。如果您選擇了,您甚至可以通過傳遞給腳本的參數來設置開關。

注意輸出可能更多,你正在尋找,但至少試一試。此外,這將無法在Powershell ISE中運行,因爲您將收到錯誤Start-Transcript : This host does not support transcription.

+0

的我想要的庫函數不必是加上任何日誌記錄實施。我希望調用者能夠決定它對函數的輸出做什麼。 – user1054637 2014-08-28 15:58:45

+0

使用另一種方法進行了更新。如果我再次誤解了你的需求,請告訴我。 – Matt 2014-08-28 16:15:50

1

另一種方法是返回一個包含結果和日誌信息的複合對象。這很容易分開。

function MyFunc 
{ 

    # initialize 
    $result = $null 
    $log = @() 

    # write to the log 
    $log += "This will be written to the log" 
    $log += "So will this" 

    # record the result 
    $result = $true 

    # return result and log combined into object 
    return New-Object -TypeName PSObject -Property @{ result = $result; log = $log -join "`r`n" } 

} 

# Call the function and get the results 
$MyFuncResult = MyFunc 

# Display the returned result value 
Write-Host ("MyFunc Result = {0}" -f $MyFuncResult.Result) 

# Display the log 
write-host ("MyFunc Log = {0}" -f $MyFuncResult.Log) 

或者,如果要避免該對象,請通過引用傳入日誌變量。該函數可以寫入日誌變量,並且更改將在調用作用域中可見。爲此,需要將[ref]前綴添加到函數定義和函數調用中。當您在函數中寫入變量時,您需要參考.value屬性。

function MyFunc2 ([ref]$log) 
{ 

    # initialize 
    $result = $null 

    # write to the log 
    $log.value += "`r`nThis will be written to the log" 
    $log.value += "`r`nSo will this" 

    # record the result 
    $result = $true 

    # return result and log combined into object 
    return $result 

} 

# Call the function and get the results 
$log = "before MyFunc2" 
$MyFuncResult = MyFunc2([ref]$log) 
$log += "`nafter MyFunc2" 

# Display the returned result value 
write-host ("MyFunc2 result = {0}" -f $MyFuncResult) 

# Display the log 
write-host ("MyFunc2 Log = {0}" -f $Log)