【问题标题】:Powershell log - count errorsPowershell 日志 - 计数错误
【发布时间】:2018-05-10 18:34:15
【问题描述】:

我有一个基本的 Powershell 脚本,它将网络活动(tracert、nslookup、ping)记录到日志文件中。每天都会创建一个新的日志文件。

我想更新脚本以保存错误发生的信息。 我有一系列可能的错误(我感兴趣),当将信息保存到日志文件时,我希望记录任何错误 - 只计算每个错误。

我可以将错误计数以这种形式保存在文本文件中: error_namecount|error_namecount .. 等 例如: 主机不可用*10|请求超时*22 ..等

假设我的这个数组有错误:

$errors = @('error1','error2','error3')

我将结果保存到这样的日志文件中:

tracert $server >> $logFile
nslookup $server >> $logFile
ping $server >> $logFile

我尝试将输出保存到变量并将其与数组匹配:

tracert $server >> $logFile
$data = tracert $server
if ($null -ne ($errors | ? { $data -match $_ })) {
    #reading data from report file
    $data = Get-Content $reportFile
    $d1 = $data.split('|')
    $err = @()
    foreach ($item in $d) {
        $count = $item.split('*')
        $err += $count[1]
    }
}

我无法弄清楚的是如何获取数组键,以便从报告文件中读取正确的错误数量,如果发生错误可以增加,然后再次保存文件。也许还有其他更简单的解决方案? 我将不胜感激任何帮助或提示。

【问题讨论】:

    标签: powershell logging networking


    【解决方案1】:

    你需要的是 try/catch:

    try{tracert $server >> $logFile}
    catch{$_.Exception.Message}
    

    把真正的代码放到try块里,如果失败,就会来catch块,$_.Exception.Message会捕获错误信息。如果您希望获得整个错误,那么您可以在 catch 块中使用$Error

    现在您可以相应地更改脚本并删除if 逻辑。

    由于您已经有了可能的错误代码,您可以通过字符串匹配将Switch case 放入可能原因的catch 块中,并可以放入您自己的句子。

    【讨论】:

      【解决方案2】:

      我建议不要创建自己的自定义输出格式,然后必须通过字符串操作来处理,而是使用 PowerShell 已经允许您访问的结构化格式之一。例如,JSON。

      我可以这样写:

      Function Out-ErrorLog {
      
          [CmdletBinding()]
          Param(
              [Parameter(ValueFromPipeline=$true)]
              [String]$Data,
      
              [String]$LogPath = '.\error.log',
      
              [String[]]$Errors  = @('Request Timed Out','Host Not Available')
          )
          Process {
              If (Test-Path $LogPath) { 
                  Write-Verbose "Loading existing error log file from $LogPath.."
                  $ErrorLog = Get-Content $LogPath | ConvertFrom-Json
              } Else {
                  $ErrorLog = New-Object -TypeName PSObject 
              }
      
              ForEach ($Err in $Errors) { 
                  $Matches = $Data | Select-String -SimpleMatch $Err -AllMatches
      
                  If ($Matches) {
                      If (-Not $ErrorLog.$Err) {
                          Write-Verbose "Creating $Err property.."
                          $ErrorLog | Add-Member -MemberType NoteProperty -Name $Err -Value $Matches.count
                      } Else {
                          Write-Verbose "Adding to $Err count.."
                          $ErrorLog.$Err += $Matches.count 
                      }
                  }
              } 
      
              Write-Verbose "Outputting Errors to $LogPath.."
              $ErrorLog | ConvertTo-Json | Out-File $LogPath -Encoding UTF8
          }
      }
      
      $Server  = '1.2.3.4'
      
      $Data = ping $Server
      $Data >> $LogFile
      $Data | Out-ErrorLog -Verbose
      
      $Data = tracert $Server
      $Data >> $LogFile
      $Data | Out-ErrorLog -Verbose
      
      $Data = nslookup $server
      $Data >> $LogFile
      $Data | Out-ErrorLog -Verbose
      

      我编写了一个Out-ErrorLog 函数来节省代码重复。这将 $Data 作为管道的输入,并有两个其他参数 $LogPath 用于您希望将错误记录为文件的位置以及您要测试/记录的 $Errors 数组。

      然后它使用Test-Path 来查看它的日志文件是否已经存在,如果存在则加载它并从 Json 转换它的内容。

      然后我们使用ForEach 循环遍历错误选项并将它们与提供的数据进行匹配。我们为此使用Select-String-AllMatches 参数,以便我们可以轻松计算发生了多少错误。

      如果发生了错误,那么我们检查是否已经在$ErrorLog 对象中存在错误。如果我们不这样做,那么我们在我们的对象中为该错误创建一个新属性,并给它计数的值。如果它已经存在,那么我们只是增加它。

      当循环结束时,我们将生成的 ErrorLog 对象输出为 Json 文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-27
        • 1970-01-01
        • 2013-02-13
        • 2020-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多