This script can be used to parse either
the “SnapMirror-Status” or “SnapVault-Status-L” files from AutoSupport. You
might want to do this if you’re curious to know the transfer rate of your
relations. One special feature, is that it uses computational mathematics to
work out a transfer rate as if the SnapMirror/SnapVault wasn’t contending with
other SnapMirrors/SnapVaults - i.e. was running independent and not concurrent
with other jobs (where jobs conflict of course) - this metric is called “Transfer
Rate Adjusted” or “T.Rate Adj” for short, and the script also works out the
average and median of these values too. The output is a CSV.
Will be surprised if this script gets
much use, but the code is possibly interesting.
########################
## SM_SV_analysis.ps1 ##
########################
# This tool is designed to analyze the following
files from 7-Mode ASUPs:
# SNAPMIRROR-STATUS
# SNAPVAULT-STATUS-L
Param([parameter(Mandatory=$true)][String]$FileIn)
If(!(Test-Path $FileIn)){ Write-Host "Unable to
find $FileIn"; EXIT}
## PROCESS THE SM/SV STATUS ##
$SVstatus = Get-Content $FileIn
[System.Object]$SVdata = @{}
[Boolean]$Recording = $FALSE
$Count = 0
[System.Array]$Starts = @()
$SVstatus | foreach {
If($_.StartsWith("Source")){
$Recording
= $TRUE
$Count++
[System.Object]$SVdata.$Count = @{}
[String]$Source = $_.Split(":")[1].Trim("
","`t") + ":" + $_.Split(":")[2].Trim("
","`t")
}
If($Recording){
If($_.StartsWith("Destination")){
[String]$Destination = $_.Split(":")[1].Trim("
","`t") + ":" + $_.Split(":")[2].Trim("
","`t")
}
If($_.StartsWith("Status")){ ## Drop if not idle at time of
SM/SV status
If( !($_
-Match ("Idle")) ){ $Recording = $FALSE; $Count--; Write-Host
"DETECTED STATUS NOT IDLE!" }
}
If($_.StartsWith("Lag")){
If($_
-Match ("-")){ ## Drop if Lag is "-"
$Recording = $FALSE; $Count--; Write-Host 'DETECTED LAG = "-"'
} else{
[Int]$Hours =
[Int]($_.Split(":")[1].Trim(" ","`t"))
[Int]$Minutes = [Int]($_.Split(":")[2].Trim("
","`t"))
[Int]$Seconds = [Int]($_.Split(":")[3].Trim("
","`t"))
[Int]$Lag = $Seconds +
(60*$Minutes) + (60*60*$Hours)
}
}
If($_.StartsWith("Mirror Timestamp")){
[String]$MirrorTS = $_.Substring(17).Trim(" ","`t")
}
If($_.StartsWith("Last Transfer Size")){
[Int]$Size =
[Int]($_.Split(":")[1].Trim("
","`t").Split(" ")[0])
}
If($_.StartsWith("Last Transfer Duration")){
[Int]$Hours =
[Int]($_.Split(":")[1].Trim(" ","`t"))
[Int]$Minutes =
[Int]($_.Split(":")[2].Trim(" ","`t"))
[Int]$Seconds =
[Int]($_.Split(":")[3].Trim(" ","`t"))
[Int]$Duration
= $Seconds + (60*$Minutes) + (60*60*$Hours)
[Int]$StartSecond = $Lag + $Duration
If($Duration -ne 0){ [Double]$TRate
= ($Size/$Duration) } else { [Double]$TRate = 0 }
[String]$SVdata.$Count.Source
= $Source
[String]$SVdata.$Count.Destination
= $Destination
[String]$SVdata.$Count.MirrorTS
= $MirrorTS
[Int]$SVdata.$Count.Start
= $StartSecond
[Int]$SVdata.$Count.Duration
= $Duration
[Int]$SVdata.$Count.Size
= $Size
[Double]$SVdata.$Count.TRate
= $TRate
$Starts
+= $StartSecond
}
}
If($_.StartsWith("Last Transfer From")){ $Recording = $FALSE }
}
[System.Array]$Starts = $Starts | Sort-Object -Descending
## WORK OUT NUMBER OF TRANSFERS RUNNING AT SECOND %J
##
[Int]$MaxGoBack = 7 * 24 * 60 * 60 ## Go back no
longer than 7 days
[System.Object]$RunningTs = @{} ## Running Transfers
per second
Write-Host "Processing $Count items for
transfers running at second X ... "
For($i=1; $i -le $Count; $i++){
Write-Host
"$i " -NoNewLine
[Int]$Start
= $SVdata.$i.Start
If($Start
-le $MaxGoBack){
[Int]$End
= $Start - $SVdata.$i.Duration
For($j =
$Start; $j -gt $End; $j--){
If(!$RunningTs.$j){ [Int]$RunningTs.$j = 0 }
$RunningTs.$j ++ ## Recording number of transfers running at second $j
}
}
}; Write-Host; Write-Host
## WORK OUT AN ADJUSTED TRANSTER RATE FOR IF THE
TRANSFER WAS RUNNING ALONE ##
Write-Host "Processing $Count items for
adjusted Transfer Rate ... "
For($i=1; $i -le $Count; $i++){
Write-Host
"$i " -NoNewLine
[Double]$UnitDenominator = 0
[Int]$Start
= $SVdata.$i.Start
If($Start
-le $MaxGoBack){
[Int]$End
= $Start - $SVdata.$i.Duration
For($j =
$Start; $j -gt $End; $j--){
$UnitDenominator += 1 / $RunningTs.$j
}
}
If($UnitDenominator -ne 0){ [Double]$TRateAdj = $SVdata.$i.Size /
$UnitDenominator } else { [Double]$TRateAdj = 0 }
[Double]$SVdata.$i.TRateAdj = $TRateAdj
}; Write-Host; Write-Host
## GENERATE OUTPUT ##
[System.Array]$AllTRateAdj = @()
[System.Array]$Output = "Start (s),Size
(KB),Duration (s),T.Rate (KB/s),T.Rate Adj (KB/s),Mirror
Timestamp,Source,Destination"
$Starts | Foreach {
For($i=1;$i
-le $Count;$i++){
If($SVdata.$i.Start -eq $_){
If($SVdata.$i.TRateAdj -ne 0){ $AllTRateAdj += $SVdata.$i.TRateAdj }
$Output
+= ([String]$_ + "," + [String]$SVdata.$i.Size + "," +
[String]$SVdata.$i.Duration + "," + [String]$SVdata.$i.TRate +
"," + [String]$SVdata.$i.TRateAdj + "," +
$SVdata.$i.MirrorTS + "," + $SVdata.$i.Source + "," +
$SVdata.$i.Destination)
}
}
}
## FIND THE AVERAGEand MEDIAN OF of T.Rate Adj ##
$Average = ($AllTRateAdj | measure -average).Average
$AllTRateAdj = $AllTRateAdj | sort
If ($AllTRateAdj.count%2) { $MedianValue =
$AllTRateAdj[[math]::Floor($AllTRateAdj.count/2)] } # ODD
else { $MedianValue =
($AllTRateAdj[$AllTRateAdj.Count/2],$AllTRateAdj[$AllTRateAdj.count/2-1]
|measure -Average).average }
Write-Host ("Transfer Rate Adjusted (KB/s)
Average = " + [String]$Average)
Write-Host ("Transfer Rate Adjusted (KB/s)
Median = " + [String]$MedianValue)
$Output += (",,,AVERAGE =," +
[String]$Average)
$Output += (",,,MEDIAN =," +
[String]$MedianValue)
## OUTPUT TO CSV ##
$Output | Out-File ($FileIn + ".CSV")
-Encoding Default
Write-Host ("Output file $FileIn" +
".CSV created!"); Write-Host
## THE END ##
Comments
Post a Comment