1import sys
2from datetime import datetime
3from threading import Thread
4import Queue
5
6from boto.utils import RequestHook
7from boto.compat import long_type
8
9
10class RequestLogger(RequestHook):
11    """
12    This class implements a request logger that uses a single thread to
13    write to a log file.
14    """
15    def __init__(self, filename='/tmp/request_log.csv'):
16        self.request_log_file = open(filename, 'w')
17        self.request_log_queue = Queue.Queue(100)
18        Thread(target=self._request_log_worker).start()
19
20    def handle_request_data(self, request, response, error=False):
21        len = 0 if error else response.getheader('Content-Length')
22        now = datetime.now()
23        time = now.strftime('%Y-%m-%d %H:%M:%S')
24        td = (now - request.start_time)
25        duration = (td.microseconds + long_type(td.seconds + td.days * 24 * 3600) * 1e6) / 1e6
26
27        # write output including timestamp, status code, response time, response size, request action
28        self.request_log_queue.put("'%s', '%s', '%s', '%s', '%s'\n" % (time, response.status, duration, len, request.params['Action']))
29
30    def _request_log_worker(self):
31        while True:
32            try:
33                item = self.request_log_queue.get(True)
34                self.request_log_file.write(item)
35                self.request_log_file.flush()
36                self.request_log_queue.task_done()
37            except:
38                import traceback
39                traceback.print_exc(file=sys.stdout)
40