Circular Logging with Process Monitor

Process Monitor (ProcMon) is the goto utility to capture system events like file system or registry access. It is very useful when you need to collect information from your system for troubleshooting purposes. More often than not, vendors like Microsoft or Citrix ask you to upload a trace file created with ProcMon to enable them to assist you with troubleshooting.

However, some problems are not easy to reproduce and therefore difficult to capture with Process Monitor. ProcMon can capture a lot of data but in the process it creates large logfiles. Leaving ProcMon running for an extended period of time will fill up your disk very soon, especially if it is run in a XenApp environment with dozens of users working on the same machine.

One thing Process Monitor does not do is circular tracing. Circular tracing (or circular logging) works by overwriting old events with new events and keeps the logfile on a given size.

I have written a script that adds this functionality to Process Monitor. It allows you to specify how many log files you would like to keep and how many seconds you want to capture in each log file. 6 log files with each containing 5 minutes (300 seconds) of past events will allow you to keep the required disk space to a minimum while having 30 minutes to react and stop the trace once the error appears.

ProcMon files grow big pretty fast but they can be compressed easily. My script will automatically compress past log files to further limit the disk space required before they are being rolled over.

$LogPath="C:\ProcMon"
$MaxLogs=5
$Counter = 0

do
{
  $Counter = $Counter+1

  #Reset counter if $MaxLogs is reached
  If($Counter -gt $MaxLogs)
  {
     $Counter = 1
  }

  $Logfile = $LogPath+"\Logfile_"+$counter+".pml"
  $Zipfile = $LogPath+"\Logfile_"+$Counter+".zip"
  $ProcMonParameters = "/Backingfile $Logfile /AcceptEula /Minimized /Quiet"

  # Remove old compressed log files to enable roll over
  If(Test-Path $Zipfile)
  {
    Remove-Item $Zipfile
  }

  # Start ProcMon for 5 minutes
  start-process $LogPath\procmon.exe $ProcMonParameters
  Start-Sleep -Seconds 300

  # Terminate ProcMon
  C:\ProcMon\procmon.exe /Terminate
  Start-Sleep 3

  # Compress log files and remove trace files
  Compress-Archive -path $LogPath\"Logfile_"$counter*".pml" -DestinationPath $Zipfile
  Remove-Item $Logpath\*.pml
}
while ($Counter -le $MaxLogs)

4 thoughts on “Circular Logging with Process Monitor

  1. Hey kind sir – Do you have a way to to this part on PS 4.0?
    Compress-Archive -path $LogPath\”Logfile_”$counter*”.pml” -DestinationPath $Zipfile

    I can’t install 5 on the production server or reboot it but really want this function.

    Thank you!!

    Like

    • What about something like…?

      $Source = $LogPath\”Logfile_”$counter*”.pml”
      Add-Type -assembly system.io.compression.filesystem
      [io.compression.zipfile]::CreateFromDirectory($source, $Zipfile)

      Like

  2. Let me know if this helps

    $LogPath = “C:\ProcMon”
    $Counter = 0
    $MaxLogs = 3
    $timer = 300

    # ————————————————————

    function collect($Logfile){

    # delete($Logfile)

    $ProcMonParameters = “/Backingfile $Logfile /AcceptEula /Minimized /Quiet”
    # Start ProcMon for x minutes
    start-process $LogPath\procmon.exe $ProcMonParameters
    Start-Sleep -Seconds $timer
    # Terminate ProcMon
    C:\ProcMon\procmon.exe /Terminate
    Start-Sleep -Seconds 10
    }

    function zip($Zipfile){

    delete($Zipfile)

    # Compress log files and remove trace files
    $aux = $LogPath+”\Logfile_”+($Counter-1)+”.pml”
    Compress-Archive -path $aux -DestinationPath $Zipfile
    delete($aux)
    # Start-Sleep -Seconds 5
    }

    function delete($var){

    # Remove old compressed log files to enable roll over

    If(Test-Path $var) {
    Remove-Item $var
    }

    }

    # ————————————————————

    do{

    if($Counter -gt 1){
    $Zipfile = $LogPath+”\Logfile_”+($Counter-1)+”.zip”
    zip($Zipfile)
    }

    $Counter = $Counter+1
    $Logfile = $LogPath+”\Logfile_”+$Counter+”.pml”

    #Reset counter if $MaxLogs is reached
    If($Counter -gt $MaxLogs){
    $Zipfile = $LogPath+”\Logfile_”+($Counter-1)+”.zip”
    zip($Zipfile)

    $Counter = 0

    } else {

    collect($Logfile)

    }

    } while ($Counter -le $MaxLogs)

    $LogPath = “C:\ProcMon”
    $Counter = 0
    $MaxLogs = 3
    $timer = 300

    # ————————————————————

    function collect($Logfile){

    # delete($Logfile)

    $ProcMonParameters = “/Backingfile $Logfile /AcceptEula /Minimized /Quiet”
    # Start ProcMon for x minutes
    start-process $LogPath\procmon.exe $ProcMonParameters
    Start-Sleep -Seconds $timer
    # Terminate ProcMon
    C:\ProcMon\procmon.exe /Terminate
    Start-Sleep -Seconds 10
    }

    function zip($Zipfile){

    delete($Zipfile)

    # Compress log files and remove trace files
    $aux = $LogPath+”\Logfile_”+($Counter-1)+”.pml”
    Compress-Archive -path $aux -DestinationPath $Zipfile
    delete($aux)
    # Start-Sleep -Seconds 5
    }

    function delete($var){

    # Remove old compressed log files to enable roll over

    If(Test-Path $var) {
    Remove-Item $var
    }

    }

    # ————————————————————

    do{

    if($Counter -gt 1){
    $Zipfile = $LogPath+”\Logfile_”+($Counter-1)+”.zip”
    zip($Zipfile)
    }

    $Counter = $Counter+1
    $Logfile = $LogPath+”\Logfile_”+$Counter+”.pml”

    #Reset counter if $MaxLogs is reached
    If($Counter -gt $MaxLogs){
    $Zipfile = $LogPath+”\Logfile_”+($Counter-1)+”.zip”
    zip($Zipfile)

    $Counter = 0

    } else {

    collect($Logfile)

    }

    } while ($Counter -le $MaxLogs)

    Like

  3. What I did was reimplement the code to avoid collisions during the process of capturing, compressing and deleting the Procmon traces. I think the code is now a bit more refined. Please feel free to modify the code to improve it.

    Thanks

    Like

Leave a comment