3

我正在尝试获取耗时超过 999 毫秒的请求的准确计数。我试过使用这个脚本:

http://wingleungchan.blogspot.com/2011/04/parsing-iis-logs-with-powershell.html

但它不能准确地提取大于 999 的数字。在 Powershell 中是否有一种有效的方法来对基于整数的 IIS(W3C) 字段进行排序?

仅供参考:我正在运行 Windows 2008。请不要建议我使用 Log Parser。谢谢!

4

2 回答 2

1

导入 Iis 日志

由于问题中的赞成评论发布的有用链接(https://poshcode.org/2574)已损坏,以下是网页上的原始内容(PowerShell脚本)(以防对任何人有帮助):

Mark Shevchenko 的 Import-Iis-Log

读入以*logW3C 格式保存的 IIS 文件。

Import-Iis-Logcmdlet 为您提供了一种从 IIS*log文件(以 W3C 格式保存)中读取数据,然后在 Windows PowerShell 控制台中以表格格式显示该数据的方法。

参数:

  • Path(string, required, position = 0, value from pipeline, not null, not empty) 指定要导入的 IIS *.log 文件的路径。您还可以通过管道将路径导入 Import-Iss-Log。

  • Delimiter(string, position = 1, not null, not empty) 指定分隔 IIS *log 文件中的属性值的分隔符。默认值为空格键。

  • Encoding(Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding) IIS *.log 文件的字符编码。默认值为 UTF8。

管道对象中的 cmdlet 输出具有以下属性:

DateTime(System.DateTime) 日志的组合“日期”和“时间”值。

ClientHost(System.Net.IpAddress) 日志的“c-ip”值。

UserName(匿名用户的字符串或 $null)日志的“cs-username”值。

Service(字符串)日志的“s-sitename”值。

Machine(字符串)日志的“s-computername”值。

ServerIp(System.Net.IpAddress) 日志的“s-ip”值。

ServerPort(int) 日志的“s-port”值。

Method(字符串)日志的“cs-method”值。

ScriptPath(字符串)日志的“cs-uri-stem”值,使用 System.Web.HttpUtility.UrlDecode 解码。

QueryString(字符串或 $null 用于没有查询字符串的 HTTP 请求)日志的“cs-uri-query”值,使用 System.Web.HttpUtility.UrlDecode 解码。

ServiceStatus(int) 日志的“sc-status”值。

ServiceSubStatus(int) 日志的“sc-substatus”值。

Win32Status(int) 日志的“sc-win32-status”值。

BytesSent(System.UInt64) 日志的“sc-bytes”值。

BytesRecived(System.UInt64) 日志的“cs-bytes”值。

ProcessingTime(int) 日志的“耗时”值。

ProtocolVersion(字符串)日志的“cs-version”值。

Host(不带 Host 标头的 HTTP 请求的 $null 字符串)日志的“cs-host”值。

UserAgent(对于没有 User-Agent 标头的请求的字符串或 $null)“cs(User-Agent)”日志的值。

Cookie(对于没有 cookie 的请求,字符串或 $null)“cs(Cookie)”日志的值。

Referer(对于没有引用者的请求,字符串或 $null)“cs(Referer)”日志的值,使用 System.Web.HttpUtility.UrlDecode 解码。

param
(
    [Parameter(
        Mandatory=$true,
        Position = 0,
        ValueFromPipeline=$true,
        HelpMessage="Specifies the path to the IIS *.log file to import. You can also pipe a path to Import-Iss-Log."
    )]
    [ValidateNotNullOrEmpty()]
    [string]
    $Path,
    
    [Parameter(
        Position = 1,
        HelpMessage="Specifies the delimiter that separates the property values in the IIS *.log file. The default is a spacebar."
    )]
    [ValidateNotNullOrEmpty()]
    [string]
    $Delimiter = " ",
    
    [Parameter(HelpMessage="The character encoding for the IIS *log file. The default is the UTF8.")]
    [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]
    $Encoding = [Microsoft.PowerShell.Commands.FileSystemCmdletProviderEncoding]::UTF8
)
    
begin
{
    $fieldNames = @()
    
    $output = New-Object Object
    Add-Member -InputObject $output -MemberType NoteProperty -Name "DateTime" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ClientHost" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "UserName" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "Service" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "Machine" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ServerIp" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ServerPort" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "Method" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ScriptPath" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "QueryString" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ServiceStatus" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ServiceSubStatus" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "Win32Status" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "BytesSent" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "BytesRecived" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ProcessingTime" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "ProtocolVersion" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "Host" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "UserAgent" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "Cookie" -Value $null
    Add-Member -InputObject $output -MemberType NoteProperty -Name "Referer" -Value $null
}

process
{
    foreach($line in Get-Content -Path $Path -Encoding $Encoding)
    {
        if($line.StartsWith("#Fields: "))
        {
            $fieldNames = @($line.Substring("#Fields: ".Length).Split($Delimiter));
        }
        elseif(-not $line.StartsWith("#"))
        {
            $fieldValues = @($line.Split($Delimiter));
            
            for($i = 0; $i -lt $fieldValues.Length; $i++)
            {
                $name = $fieldNames[$i]
                $value = $fieldValues[$i]
                
                switch($name)
                {
                "date" { $output.DateTime = [DateTime]::Parse($value) }
                "time" { $output.DateTime += [TimeSpan]::Parse($value) }
                "c-ip" { $output.ClientHost = [System.Net.IPAddress]::Parse($value) }
                "cs-username" { $output.UserName = if($value -eq '-') { $null } else { $value } }
                "s-sitename" { $output.Service = $value }
                "s-computername" { $output.Machine = $value }
                "s-ip" { $output.ServerIp = [System.Net.IPAddress]::Parse($value) }
                "s-port" { $output.ServerPort = [int]$value }
                "cs-method" { $output.Method = $value }
                "cs-uri-stem" { $output.ScriptPath = [System.Web.HttpUtility]::UrlDecode($value) }
                "cs-uri-query" { $output.QueryString = if($value -eq '-') { $null } else { [System.Web.HttpUtility]::UrlDecode($value) } }
                "sc-status" { $output.ServiceStatus = [int]$value }
                "sc-substatus" { $output.ServiceSubStatus = [int]$value }
                "sc-win32-status" { $output.Win32Status = [BitConverter]::ToInt32([BitConverter]::GetBytes([UInt32]($value)), 0) }
                "sc-bytes" { $output.BytesSent = [UInt64]$value }
                "cs-bytes" { $output.BytesRecived = [UInt64]$value }
                "time-taken" { $output.ProcessingTime = [int]$value }
                "cs-version" { $output.ProtocolVersion = $value }
                "cs-host" { $output.Host = if($value -eq '-') { $null } else { $value } }
                "cs(User-Agent)" { $output.UserAgent = if($value -eq '-') { $null } else { $value } }
                "cs(Cookie)" { $output.Cookie = if($value -eq '-') { $null } else { $value } }
                "cs(Referer)" { $output.Referer = if($value -eq '-') { $null } else { [System.Web.HttpUtility]::UrlDecode($value) } }
                }
            }
            
            Write-Output $output
        }
    }
}

来源:https ://web.archive.org/web/20170430094952/https://poshcode.org/2574

于 2021-03-18T09:35:24.927 回答
0

ConvertFrom-Csv works pretty well. You need to strip out the comment lines and provide a list of headers.

$headers @("Date", "Time", ..., "TimeTaken")
Get-Content "u_ex130815.log" | select -Skip 4| ConvertFrom-Csv -Delimiter " " -Header $headers | ? timetaken -gt 999
于 2014-01-08T21:39:26.507 回答