Convert IIS log to CSV - Python script

Hello. I suck at Python, but I’m trying to get better.

Recently, I had the need to look through a massive IIS log because one of our catalogues was running bog-slow due to a Googlebot “incident.” Basically Googlebot was hammering the server and things weren’t running right.

As a database guy, every problem is a nail table and my solution is usually a hammer database. So my thought was, can I convert this IIS log into a CSV? Then I could work with it in a spreadsheet or, better yet, dump it into a database like SQLite or MariaDB. I’m sure something like this might already exist, but if I download it or copy and paste it, I don’t learn anything, do I?

Anyway, this may be useful to someone out there. It’s a terminal based Python script that accepts an IIS log as an argument and then spits out a CSV with the same name as the IIS log. So something like:

python3 iis2csv.py u_ex250517.log

No lie, there’s nothing groundbreaking here. But hey, it’s already helped me with a couple of other IIS things so give it a spin if you like.

# Standard imports
import csv
import sys
import os

def convert_iis_log_to_csv(iis_log_path):
    try:
        with open(iis_log_path, 'r', encoding='utf-8') as log_file:
            lines = log_file.readlines()
    except FileNotFoundError: # Oop, file not found
        print(f"Error: File not found: {iis_log_path}")
        sys.exit(1)

    # Set up some arrays
    field_names = []
    data_lines = []

    # Read the file
    for line in lines:
        line = line.strip()
        if line.startswith("#Fields:"): # Look for the Fields line in the IIS log and use that to make column headers
            field_names = line[len("#Fields:"):].strip().split()
        elif line.startswith("#") or not line:
            continue  # Skip any blank or commented lines
        else:
            data_lines.append(line.split())

    if not field_names: # If no Fields line, it'll error, so you really want the Fields line in the file
        print("Error: No '#Fields:' line found in the log file.")
        sys.exit(1)

    base_name = os.path.splitext(os.path.basename(iis_log_path))[0]
    output_csv_path = f"{base_name}.csv" # The CSV will be the same file name as the log file

    # Create the CSV
    with open(output_csv_path, 'w', newline='', encoding='utf-8') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow(field_names)
        writer.writerows(data_lines)

    print(f"Conversion complete. CSV written to: {output_csv_path}")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python convert_iis_log.py iis_log_file") # The most obvious help statement ever
        sys.exit(1)

    iis_log_path = sys.argv[1]
    convert_iis_log_to_csv(iis_log_path)
1 Like

This makes me recall the days when I regularly used OpenRefine (née Google Refine) for handling the absolute insanity that is Polaris SIP logs.

OpenRefine probably still works just fine for this task, but thankfully we’ve been relying on SIP less, and we also have @mfields SIP Testing Tool – Central Library Consortium

1 Like