I’ve been working a lot with performance and performance
tuning over the last few months. This is
an area I have a pretty heavy background in and I always enjoy the chance to
work with. Although somewhat of a mysterious
art there are tools out there that make it far easier; the first among these being
Performance Analysis of Logs (PAL) by Clint
Huffman. It is the most valuable tool I
know of when working with performance analysis on the Windows platform. PAL continues to be updated regularly and
even had a release earlier this month (thanks Clint). PAL was the first tool that ever got me
really thinking about PowerShell and I have to say the more I get into
PowerShell the more amazed I am by it.
It’s like everything I liked from UNIX and everything I still love about
Windows (and more).
Today I had a request to time box the performance logs I’ve
been running (templates from PAL) to working hours for a client. This would require filtering out segments of
time from the perf logs (PAL will let you pick start and end dates/times, but
only one of each). While looking for
solutions I thought about ways to edit the log files. Working with binary perfmon files has never
seemed easy to me and everyone I ask seems to not really know how to do
it. Some offer up relog.exe as a
solution (and it is a good solution) but I wanted to automate this process and
I thought it’d be more work. This would
work with PAL though because as of version 2.0 it can take log files as a list
and process them together (as one logical log).
As I thought about how to do this I turned to Bing hoping there would be a PowerShell
solution to my predicament. I was NOT to
be disappointed by the power that is PowerShell. First I found the import-counter cmdlet and
saw I could iterate over each PerformanceCounterSampleSet and even check the
Timestamp property (kudos to Allen
White for this BTW). After playing
around with this I realized I could actually pipe this to the Where-Object
cmdlet to filter my selection. A little
deeper digging and I quickly realized I could ditch the iteration altogether and
pipe these cmdlets to the export-counter cmdlet. The result was this:
$logWindowStart = '09:00:00'
$logWindowEnd = '17:00:00'
$sunday = (Get-Date 2011/11/20).DayOfWeek
$saturday= (Get-Date 2011/11/19).DayOfWeek
import-counter $logfile | where {$_.Timestamp.TimeOfDay -gt
$logWindowStart -and $_.Timestamp.TimeOfDay -lt $logWindowEnd -and
$_.Timestamp.DayOfWeek -gt $sunday -and $_.Timestamp.DayOfWeek -lt $saturday} |
export-counter -path $outputFile
The input and output filenames are parameters to the script
and the hard coded dates don’t really matter because they’re just used to get
DayOfWeek enums. Hopefully this can be useful
to someone else as well.