<# .Synopsis 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_.csv .Parameter LastWeek Optional switch to retrieve logs of the previous week (Monday to Sunday) .Parameter Last Optional number to retrieve 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 .Notes Author Michel GELDENHUYS - NetApp Luxembourg - mg@netapp.com 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 = $false ) $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