├── README.md └── apache-log-replay.py /README.md: -------------------------------------------------------------------------------- 1 | # Script to replay HTTP requests from an Apache access logfile 2 | 3 | Features 4 | 5 | - Takes the time between requests into account 6 | - Replaying can be sped up by a given factor 7 | - Optionally send all requests to a selected (proxy) server 8 | 9 | ## Installation 10 | 11 | Requires Python >= 2.6 12 | 13 | Simply download the file and execute it... 14 | 15 | ## Usage 16 | 17 | Usage: apache-log-replay.py [options] logfile 18 | 19 | Options: 20 | -h, --help show this help message and exit 21 | -p PROXY, --proxy=PROXY 22 | send requests to server PROXY 23 | -s SPEEDUP, --speedup=SPEEDUP 24 | make time run faster by factor SPEEDUP -------------------------------------------------------------------------------- /apache-log-replay.py: -------------------------------------------------------------------------------- 1 | """Replay requests from an HTTP access log file. 2 | 3 | - Takes time between requests into account, with option to speed up the replay. 4 | - Allows one to send all requests to a selected server (proxy). 5 | """ 6 | 7 | import sys 8 | import time 9 | import urllib2 10 | from datetime import datetime 11 | from optparse import OptionParser 12 | 13 | # Constants that specify access log format (indices 14 | # specify position after splitting on spaces) 15 | HOST_INDEX = 0 16 | TIME_INDEX = 3 17 | PATH_INDEX = 6 18 | 19 | def main(filename, proxy, speedup=1): 20 | """Setup and start replaying.""" 21 | requests = _parse_logfile(filename) 22 | _setup_http_client(proxy) 23 | _replay(requests, speedup) 24 | 25 | def _replay(requests, speedup): 26 | """Replay the requests passed as argument""" 27 | total_delta = requests[-1][0] - requests[0][0] 28 | print "%d requests to go (time: %s)" % (len(requests), total_delta) 29 | last_time = requests[0][0] 30 | for request_time, host, path in requests: 31 | time_delta = (request_time - last_time) // speedup 32 | if time_delta: 33 | if time_delta and time_delta.seconds > 10: 34 | print "(next request in %d seconds)" % time_delta.seconds 35 | time.sleep(time_delta.seconds) 36 | last_time = request_time 37 | url = "http://" + host + path 38 | try: 39 | req_result = "OK" 40 | urllib2.urlopen(url) 41 | except Exception: 42 | req_result = "FAILED" 43 | print ("[%s] REQUEST: %s -- %s" 44 | % (request_time.strftime("%H:%M:%S"), url, req_result)) 45 | 46 | def _setup_http_client(proxy): 47 | """Configure proxy server and install HTTP opener""" 48 | proxy_config = {'http': proxy} if proxy else {} 49 | proxy_handler = urllib2.ProxyHandler(proxy_config) 50 | opener = urllib2.build_opener(proxy_handler) 51 | urllib2.install_opener(opener) 52 | 53 | def _parse_logfile(filename): 54 | """Parse the logfile and return a list with tuples of the form 55 | (, , ) 56 | """ 57 | logfile = open(filename, "r") 58 | requests = [] 59 | for line in logfile: 60 | parts = line.split(" ") 61 | time_text = parts[TIME_INDEX][1:] 62 | request_time = datetime.strptime(time_text, "%d/%b/%Y:%H:%M:%S") 63 | host = parts[HOST_INDEX] 64 | path = parts[PATH_INDEX] 65 | requests.append((request_time, host, path)) 66 | if not requests: 67 | print "Seems like I don't know how to parse this file!" 68 | return requests 69 | 70 | if __name__ == "__main__": 71 | """Parse command line options.""" 72 | usage = "usage: %prog [options] logfile" 73 | parser = OptionParser(usage) 74 | parser.add_option('-p', '--proxy', 75 | help='send requests to server PROXY', 76 | dest='proxy', 77 | default=None) 78 | parser.add_option('-s', '--speedup', 79 | help='make time run faster by factor SPEEDUP', 80 | dest='speedup', 81 | type='int', 82 | default=1) 83 | (options, args) = parser.parse_args() 84 | if len(args) == 1: 85 | main(args[0], options.proxy, options.speedup) 86 | else: 87 | parser.error("incorrect number of arguments") 88 | --------------------------------------------------------------------------------