2014-08-28 133 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)