Search code examples
loggingpowershelllistenerperfmon

Using a rolling log file within a Powershell script that gathers performance counters


Alright, so I've got a nice .ps1 script that gets a set of counters and writes it to a circular log file with a maximum size of 1GB. It works well, and is making everyone happy.

The way it's fired off, currently, is by a .bat file that runs through the script and then keeps an instance of Powershell.exe open in a hidden window. This allows it to run unobtrusively.

However, I'm really not liking the idea of the "Circular" log file. I'm grabbing a lot of information, and on some of these servers that means that even the 1GB limit will be getting hit fairly often. I'm running a test to see how long that actually takes, but it's foreseeable that a rolling log file might work better.

I have a function I've found to have a particular file checked for size and create a new file if necessary, but I'm not quite sure how to have that function called periodically (like, once a day or hour or something) from a Powershell script that basically is fire and forget.

To further complicate things, my experiments with start-job and stop-job in this context didn't seem to work that well. It wouldn't create the log files at all.

Code:

# This script tracks performance counters useful for tracking performance on a SQL server in a rolling .csv file 
located at a directory of your choosing. It is written for Powershell v.2

$Folder="C:\Perflogs\BBCRMLogs" # Change the bit in the quotation marks to whatever directory you want the log file 
# stored in

$Computer = $env:COMPUTERNAME
$1GBInBytes = 1GB
$p = LOTS OF COUNTERS GO HERE;

# If you want to change the performance counters, change the above list. However, these are the recommended counters for 
a client machine. 

$dir = test-path $Folder 

IF($dir -eq $False) 
{
New-Item $Folder -type directory
get-counter -counter $p -SampleInterval 60 -Continuous | Export-Counter  $Folder\SQL_log.csv -Force -FileFormat CSV 
-Circular -MaxSize $1GBInBytes
}
Else
{
get-counter -counter $p -SampleInterval 60 -Continuous | Export-Counter  $Folder\SQL_log.csv -Force -FileFormat CSV 
-Circular -MaxSize $1GBInBytes
}

Keen eyes will notice the function for rolling is missing. This is because the above script is my stable version, the function I'm using is here:

http://sysbrief.blogspot.com/2011/05/powershell-log-rotation-function.html

Any ideas? I'd prefer not to have to run a separate instance of Powershell to act as a listener, or have the user run the function themselves periodically, but I'm open to just about any idea.

Would it be better to set up a Windows job to periodically fire off the function in powershell and roll the log file?


Solution

  • You should be able to handle this inline e.g.:

    $num  = 0
    $file = "$Folder\SQL_log_${num}.csv"
    Get-Counter -counter $p -SampleInterval 60 -Continuous | 
        Foreach {
            if ((Get-Item $file).Length -gt 900MB) {
                $num +=1;$file = "$Folder\SQL_log_${num}.csv"
            }
            $_
        } | 
        Export-Counter $file -Force -FileFormat CSV -Circular -MaxSize $1GBInBytes
    

    This will test the file size continuously and when it hits a limit, it will change the filename for the log file. It is important that none of that testing/renaming script output anything. The only thing that should be output down the pipeline is the perf counter data represented by $_.