Posts for 28th October 2011

Sometimes it is useful to combine multiple log files into one to get a better picture of what is going on. To do this the following power shell scripts may be useful. These scripts are not particularly elegant, but they do perform the job required.

First step, combine the log files into one. To keep track of where a particular entry originates from then the command below will concatenate all files in the current directory into res.txt, inserting the filename and line number after the timestamp. This command assumes all files start with a timestamp of the form yyyy-mm-dd hh:mm:ss,SSS. If a different format is used then update the regex to match the new beginning of line marker.

foreach($item in Get-ChildItem ".") {$line_number = 0; [RegEx]::Matches([System.IO.File]::ReadAllText($item.FullName), "(?<LogEntry>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d.*)(?:(?:\r\n&#124;[\r\n])(?!\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d).*)*(?:\r\n&#124;[\r\n])?") &#124; %{$_.Value} &#124; %{$_.Insert(23, " " + $item.Name + " " + ($line_number++).ToString("0000000"))} &#124; %{[RegEx]::Replace($_, "[\r\n]+$", "")} &#124; Add-Content "res.txt" }

Second step, having merged all the log files into one it is necessary to sort them based on the timestamp by issuing the following command:

[RegEx]::Matches([System.IO.File]::ReadAllText("C:\Users\Ross\Desktop\logs\tmp\res.txt"), "(?<LogEntry>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d.*)(?:(?:\r\n&#124;[\r\n])(?!\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d).*)*(?:\r\n&#124;[\r\n])?") &#124; %{$_.Value} &#124; %{[RegEx]::Replace($_, "[\r\n]+$", "")} &#124; Sort &#124; Add-Content "res2.txt"

Remember to modify the path provided to ReadAllText to point to the file generated in step 1. As with step 2, if a different timestamp format is used to mark the start of log lines then change the regex to match it.