Parsing a Web Server Log File

Problem

You want to extract from a web server log file only the information you're interested in.

Solution

Pull apart the log file as follows:

while (<LOGFILE>) {
 my ($client, $identuser, $authuser, $date, $time, $tz, $method, $url, $protocol, $status, $bytes) = /^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+) "(\S+) (.*?) (\S+)" (\S+) (\S+)$/; # ... }

Discussion

This regular expression pulls apart entries in Common Log Format, an informal standard that most web servers adhere to. The fields are:

Other formats include the referrer and agent information. The pattern needs only minor changes for it to work with other log file formats. Watch out that spaces in the URL field are not escaped. This means that we can't use \S* to extract the URL. .* would cause the regex to match the entire string and then backtrack until it could satisfy the rest of the pattern. We use .*? and anchor the pattern to the end of the string with $ to make the regular expression engine match nothing and then add characters until the entire pattern is satisfied.

See Also

The CLF spec at http://www.w3.org/Daemon/User/Config/Logging.html