I got log file. My task is find lines that contain "ms 2xx", "ms 3xx", "ms 4xx", "ms 5xx". (HTTP response codes) and get output that says at what hour these responses happenned.
This code:
$logFile = "C:\Users\krivosik\Desktop\Scripts\logs\PosybeRestEPService\PosybeRestEPService20221020.log"
$response = '(?<=\d.*?ms )(2|3|4|5)\d '
# 2022.10.20 00:12:02.122
# Read the log file into memory
$logLines = Get-Content $logFile
$filteredLines = $logLines | Where-Object { $_ -match $response }
$filteredLines
gives this output(part if it ofc):
2022.10.20 18:42:01.746 | INFO | Request finished in 3.9683ms 200 application/json; charset=utf-8
2022.10.20 18:57:01.751 | INFO | Request finished in 3.8006ms 200 application/json; charset=utf-8
2022.10.20 19:10:32.105 | INFO | Request finished in 17.5819ms 202
2022.10.20 19:11:56.322 | INFO | Request finished in 31.9491ms 202
2022.10.20 19:12:01.794 | INFO | Request finished in 3.7895ms 200 application/json; charset=utf-8
2022.10.20 19:12:53.158 | INFO | Request finished in 11.0026ms 202
2022.10.20 19:13:44.859 | INFO | Request finished in 41.7799ms 202
I should get something like this(from the code):
18 ms200
18 ms200
19 ms202
19 ms202
19 ms200
19 ms202
19 ms202
I tried this but It wont have an output from all the files but just gives one hour fro example 02 and thats it. :
$logFile = "C:\Users\krivosik\Desktop\Scripts\logs\PosybeRestEPService\PosybeRestEPService20221020.log"
$response = '(?<=\d.*?ms )(2|3|4|5)\d '
# 2022.10.20 00:12:02.122
# Read the log file into memory
$logLines = Get-Content $logFile
$filteredLines = $logLines | Where-Object { $_ -match $response }
$filteredLines
$part=$filteredLines -split "\:"
$secondpart=$part[0].Trim()
$secondpart
CodePudding user response:
Since the lines in variable $filteredLines
are in CSV format (fields separated by |
) I would do the following:
$logFile = "C:\Users\krivosik\Desktop\Scripts\logs\PosybeRestEPService\PosybeRestEPService20221020.log"
$response = '(?<=\d.*?ms )(2|3|4|5)\d '
# 2022.10.20 00:12:02.122
# Read the log file into memory and convert to object array
$data = Get-Content -Path $logFile | Where-Object { $_ -match $response } |
ConvertFrom-Csv -Delimiter '|' -Header Date, Level, Status
$result = $data | ForEach-Object {
$date = [datetime]::ParseExact($_.Date.Trim(), 'yyyy.MM.dd HH:mm:ss.fff', [cultureinfo]::InvariantCulture)
$status = $_.Status -replace '^.*(ms\s \d ).*', '$1'
# output the line formatted the way you want it
'{0} {1}' -f $date.Hour, ($status -replace '\s')
}
$result
Output:
18 ms200
18 ms200
19 ms202
19 ms202
19 ms200
19 ms202
19 ms202
CodePudding user response:
You better split the columns first which allows you to easily parse the date/time properties:
$LogLines |ForEach-Object {
$Split = $_.Split('|')
$Hour = (Get-Date $Split[0]).Hour
$ms = ($Split[2] |Select-String 'ms \d\d\d').Matches.Value
Write-Host $Hour $ms
}