Last active
February 4, 2016 19:15
-
-
Save mbrownnycnyc/91c5098956ae9585a5b3 to your computer and use it in GitHub Desktop.
SnapMirror log parser to CSV
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.Synopsis | |
http://community.netapp.com/t5/Microsoft-Cloud-and-Virtualization-Discussions/SnapMirror-log-parser/td-p/43703 | |
Produce a CSV file from a specified controller snapmirror.log | |
.Description | |
Produce a CSV file from a specified controller snapmirror.log | |
.Parameter Controller | |
Storage controller which to retrieve logs from, either provide this parameter or the UseLocalLogFile parameter | |
.Parameter Out | |
Optional output file name. If not specified, output file will be in current folder | |
and will be name "smsv-parser_<controller name>.csv | |
.Parameter LastWeek | |
Optional switch to retrieve logs of the previous week (Monday to Sunday) | |
.Parameter Last | |
Optional number to retrieve <number> last lines from logs | |
.Parameter UseLocalLogFile | |
Switch to specify getting data from a saved SnapMirrorlog file instead of directly from a controller | |
.Example | |
smsv-parser.ps1 -Controller naluxfas02 | |
.Example | |
smsv-parser.ps1 -Controller naluxfas02 -Out file.csv | |
.Example | |
smsv-parser.ps1 -Controller naluxfas02 -Out file.csv -LastWeek | |
.Example | |
smsv-parser.ps1 -Controller naluxfas02 -Out file.csv -Last 50 | |
.Example | |
smsv-parser.ps1 -UseLocalLogFile $false | |
.Notes | |
Author | |
Michel GELDENHUYS - NetApp Luxembourg - [email protected] / modified by matt brown | |
Revision History | |
0.1: initial release | |
0.2: added -Last switch ; fixed xfer hash key validity detection | |
0.3: Edit by Tim McGue to allow use of saved SnapMirror log file | |
.Link | |
http://www.netapp.com/ | |
#> | |
Param( | |
[Parameter(Mandatory=$false,ValueFromPipeline=$false)] | |
[String]$Controller = "", | |
[Parameter(Mandatory=$false,ValueFromPipeline=$false)] | |
[String]$Out = "", | |
[Parameter(Mandatory=$false,ValueFromPipeline=$false)] | |
[Int]$Last = -1, | |
[Parameter(Mandatory=$false,ValueFromPipeline=$false)] | |
[Switch]$LastWeek = $false, | |
[Parameter(Mandatory=$false,ValueFromPipeline=$false)] | |
[Switch]$UseLocalLogFile = $true | |
) | |
$strProgramName = "SMSV-PARSER"; | |
$strVersion = "0.2"; | |
Set-StrictMode -Version 2 | |
$VerbosePreference = 'Continue' | |
$strPrefix = $strProgramName.ToLower() | |
If ($Out -eq "") { | |
If (!$UseLocalLogFile) { | |
$strCSVFilename = $strPrefix + "_" + $Controller + ".csv" | |
} else { | |
$strCSVFilename = $strPrefix + "_" + "results" + ".csv" | |
} | |
} else { | |
$strCSVFilename = $Out | |
} | |
$xferHash=@{} | |
Function Get-OpenFile($initialDirectory) | |
{ | |
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | | |
Out-Null | |
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog | |
$OpenFileDialog.initialDirectory = $initialDirectory | |
$OpenFileDialog.filter = "All files (*.*)| *.*" | |
$OpenFileDialog.ShowDialog() | Out-Null | |
$OpenFileDialog.filename | |
} | |
Write-Host "`nLOG REPORT FOR $strProgramName" | |
Write-Host "-----------------------------------------------------" | |
If (!$UseLocalLogFile) { | |
# Include required modules | |
if (-Not (Get-Module DataONTAP)) | |
{ | |
Import-Module DataONTAP -EA 'STOP' -Verbose:$false | |
} | |
Write-Host "Connecting to controller $Controller..." | |
# Connect to Filer and retrieve SnapMirror log | |
$filer = Connect-NAController $Controller -RPC -Transient | |
$filer.TimeoutMsec = 120000 | |
# Request SnapMirror logs from controller | |
Write-Host "Requesting logs from controller $Controller..." | |
If ($LastWeek) { | |
# If requesting logs from previous week only | |
$input_date = Get-Date | |
$dow = $input_date.DayOfWeek.Value__ | |
$temp_date = Get-Date -Year $input_date.Year -Month $input_date.Month -Day $input_date.Day ` | |
-Hour 0 -Minute 0 -Second 0 | |
$prev_week_Sunday = $temp_date.AddDays(1-$dow) | |
$prev_week_Monday = $prev_week_sunday.AddDays(-7) | |
Write-Host "Retrieving logs from" $prev_week_Monday "to" $prev_week_Sunday | |
$smlog = Get-NaSystemLog -SnapMirror -EventType dst -StartTime $prev_week_Monday -EndTime $prev_week_Sunday -Controller $filer | Select-Object * | |
} elseif (($Last -ne $null) -And ($Last -gt 0)) { | |
# Retrieving only last X records | |
$smlog = Get-NaSystemLog -SnapMirror -EventType dst -Controller $filer | Select-Object -Last $Last | |
} else { | |
$smlog = Get-NaSystemLog -SnapMirror -EventType dst -Controller $filer | Select-Object * | |
} | |
} else { | |
Write-Host "Select a saved SnapMirror log file" | |
$smlogfilename = Get-OpenFile | |
Write-Host "Reading saved SnapMirror log file" | |
$smlogtemp = Get-Content $smlogfilename | |
$smlog = @() | |
ForEach ($line in $smlogtemp) { | |
$linesplit = $line.Split(" ") | |
If ($linesplit.count -gt 9) { | |
$smlog += ,@($linesplit[6],$linesplit[7],$linesplit[8],$linesplit[9],$linesplit[4]) | |
} else { | |
$smlog += ,@($linesplit[6],$linesplit[7],$linesplit[8],"",$linesplit[4]) | |
} | |
} | |
} | |
Write-Host "Processing logs and creating CSV file..." | |
# Write CSV header | |
Out-File $strCSVFilename -Input 'source,destination,KB XFER,request time,start time,end time,request to end,start to end,request to start,Throughput KB/s' | |
# Parse log data | |
Foreach ($line in $smlog) { | |
# Available fields in smlog line: TimeStamp,TimeStampDT,EventInfo,Type,FullLine | |
If (!$UseLocalLogFile) { | |
$message = $line.EventInfo.Split(" ") | |
} else { | |
$message = $line.Split(" ") | |
} | |
# $message[0] = SM source | |
# $message[1] = SM destination | |
# $message[2] = Request type (request, start, end) | |
# $message[3] = if request = end => KB transferred | |
If ($message[2].StartsWith("Request")) { | |
# Collect request time data | |
If (!$UseLocalLogFile) { | |
$request = @{ "Request" = $line.TimeStampDT } | |
} else { | |
$request = @{ "Request" = $message[4] } | |
} | |
$xferHash.Item($message[1]) = @{} | |
$xferHash.Item($message[1]) += $request | |
} | |
If ($message[2].StartsWith("Start")) { | |
# Collect start time data | |
If (!$UseLocalLogFile) { | |
$start = @{ "Start" = $line.TimeStampDT } | |
} else { | |
$start = @{ "Start" = $message[4] } | |
} | |
$xferHash.Item($message[1]) += $start | |
} | |
If ($message[2].StartsWith("End")) { | |
# Collect end time data | |
[int]$KB = $message[3].TrimStart("(") | |
If (!$UseLocalLogFile) { | |
$end = @{ "End" = $line.TimeStampDT } | |
} else { | |
$end = @{ "End" = $message[4] } | |
} | |
$xferHash.Item($message[1]) += $end | |
If (($xferHash.Item($message[1]).ContainsKey("Request")) -And ` | |
($xferHash.Item($message[1]).ContainsKey("Start")) -And ` | |
($xferHash.Item($message[1]).ContainsKey("End"))) | |
{ | |
# If we have collected the 3 lines, let's process the date/time info to compute elapsed time between phases and throughput | |
$request_time = Get-Date $xferHash.Item($message[1]).Request | |
$start_time = Get-Date $xferHash.Item($message[1]).Start | |
$end_time = Get-Date $xferHash.Item($message[1]).End | |
$request2end = ($end_time - $request_time).TotalSeconds | |
$start2end = ($end_time - $start_time).TotalSeconds | |
$request2start = ($start_time - $request_time).TotalSeconds | |
$tput = $KB/$request2end | |
# Write data to CSV file | |
$strOutput = $($message[0],$message[1],$KB,$xferHash.Item($message[1]).Request,$xferHash.Item($message[1]).Start,$xferHash.Item($message[1]).End,$request2end,$start2end,$request2start,$tput) -Join "," | |
Out-File $strCSVFilename -Append -Input $strOutput | |
} | |
} | |
} | |
Write-Host "CSV creation completed ("$strCSVFilename").`n" | |
Trap [Exception] { | |
Write-Error $("`nERROR: " + $_.Exception.Message); | |
Write-Host $("Please run Get-Help " + $MyInvocation.InvocationName + " for more details.`n"); | |
Exit(-1); | |
} | |
# End |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment