146 lines
4.6 KiB
PowerShell
146 lines
4.6 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Summarizes upload.getFile requests in telesrv logs.
|
|
|
|
.DESCRIPTION
|
|
Use this after opening media history in TDesktop or Android. It groups
|
|
upload.getFile RPCs by client_type/app_version and reports request count and
|
|
duration percentiles. Pass -SinceLine from a previous baseline if desired.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$ServerLogPath,
|
|
[int]$SinceLine = 0,
|
|
[int]$Tail = 0,
|
|
[switch]$ShowSamples
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
$RepoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot ".."))
|
|
if (-not $ServerLogPath) {
|
|
$latestLog = Get-ChildItem (Join-Path $RepoRoot "logs") -Filter "telesrv-*.err.log" -ErrorAction SilentlyContinue |
|
|
Sort-Object LastWriteTime -Descending |
|
|
Select-Object -First 1
|
|
if ($latestLog) {
|
|
$ServerLogPath = $latestLog.FullName
|
|
} else {
|
|
$ServerLogPath = Join-Path $RepoRoot "logs\telesrv.err.log"
|
|
}
|
|
}
|
|
|
|
function Read-SharedLogLines {
|
|
if (-not (Test-Path -LiteralPath $ServerLogPath)) {
|
|
return @()
|
|
}
|
|
$stream = [System.IO.File]::Open($ServerLogPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
|
|
try {
|
|
$reader = New-Object System.IO.StreamReader($stream)
|
|
try {
|
|
$lines = New-Object System.Collections.Generic.List[string]
|
|
while (-not $reader.EndOfStream) {
|
|
$lines.Add($reader.ReadLine()) | Out-Null
|
|
}
|
|
return $lines
|
|
} finally {
|
|
$reader.Dispose()
|
|
}
|
|
} finally {
|
|
$stream.Dispose()
|
|
}
|
|
}
|
|
|
|
function Get-Field {
|
|
param([string]$Line, [string]$Name, [string]$Default = "")
|
|
if ($Line -match ('"' + [regex]::Escape($Name) + '"\s*:\s*"([^"]*)"')) {
|
|
return $Matches[1]
|
|
}
|
|
if ($Line -match ('"' + [regex]::Escape($Name) + '"\s*:\s*([^,}]+)')) {
|
|
return $Matches[1]
|
|
}
|
|
return $Default
|
|
}
|
|
|
|
function Convert-DurationMs([string]$Text) {
|
|
if (-not $Text) { return 0.0 }
|
|
if ($Text -match '^([0-9.]+)ms$') { return [double]$Matches[1] }
|
|
if ($Text -match '^([0-9.]+)s$') { return [double]$Matches[1] * 1000.0 }
|
|
if ($Text -match '^([0-9.]+)µs$') { return [double]$Matches[1] / 1000.0 }
|
|
if ($Text -match '^([0-9.]+)us$') { return [double]$Matches[1] / 1000.0 }
|
|
if ($Text -match '^([0-9.]+)ns$') { return [double]$Matches[1] / 1000000.0 }
|
|
return 0.0
|
|
}
|
|
|
|
function Percentile {
|
|
param([double[]]$Values, [double]$P)
|
|
if ($Values.Count -eq 0) { return 0.0 }
|
|
$sorted = @($Values | Sort-Object)
|
|
$idx = [int][Math]::Ceiling($P * $sorted.Count) - 1
|
|
if ($idx -lt 0) { $idx = 0 }
|
|
if ($idx -ge $sorted.Count) { $idx = $sorted.Count - 1 }
|
|
return [double]$sorted[$idx]
|
|
}
|
|
|
|
$allLines = @(Read-SharedLogLines)
|
|
$lineCount = $allLines.Count
|
|
$lines = $allLines
|
|
if ($SinceLine -gt 0) {
|
|
$lines = @($lines | Select-Object -Skip $SinceLine)
|
|
}
|
|
if ($Tail -gt 0) {
|
|
$lines = @($lines | Select-Object -Last $Tail)
|
|
}
|
|
|
|
$items = New-Object System.Collections.Generic.List[object]
|
|
foreach ($line in $lines) {
|
|
if ($line -notlike "*upload.getFile*") {
|
|
continue
|
|
}
|
|
$method = Get-Field $line "method"
|
|
if ($method -notlike "upload.getFile*") {
|
|
continue
|
|
}
|
|
$client = Get-Field $line "client_type" "unknown"
|
|
$app = Get-Field $line "app_version" ""
|
|
$dur = Convert-DurationMs (Get-Field $line "dur" "0ms")
|
|
$items.Add([pscustomobject]@{
|
|
Client = $client
|
|
AppVersion = $app
|
|
DurationMs = $dur
|
|
Line = $line
|
|
}) | Out-Null
|
|
}
|
|
|
|
Write-Host "log=$ServerLogPath"
|
|
Write-Host "total_lines=$lineCount analyzed_lines=$($lines.Count) since_line=$SinceLine upload_get_file=$($items.Count)"
|
|
Write-Host ""
|
|
|
|
if ($items.Count -eq 0) {
|
|
Write-Host "No upload.getFile entries found."
|
|
exit 0
|
|
}
|
|
|
|
$groups = $items | Group-Object Client, AppVersion
|
|
foreach ($group in $groups) {
|
|
$values = @($group.Group | ForEach-Object { [double]$_.DurationMs })
|
|
$sum = 0.0
|
|
foreach ($v in $values) { $sum += $v }
|
|
$avg = $sum / [Math]::Max(1, $values.Count)
|
|
[pscustomobject]@{
|
|
Client = ($group.Group[0].Client)
|
|
AppVersion = ($group.Group[0].AppVersion)
|
|
Count = $values.Count
|
|
AvgMs = [Math]::Round($avg, 3)
|
|
P50Ms = [Math]::Round((Percentile $values 0.50), 3)
|
|
P95Ms = [Math]::Round((Percentile $values 0.95), 3)
|
|
P99Ms = [Math]::Round((Percentile $values 0.99), 3)
|
|
MaxMs = [Math]::Round((($values | Measure-Object -Maximum).Maximum), 3)
|
|
}
|
|
}
|
|
|
|
if ($ShowSamples) {
|
|
Write-Host ""
|
|
Write-Host "Samples:"
|
|
$items | Select-Object -Last 20 | ForEach-Object { Write-Host $_.Line }
|
|
}
|